def tweetnacl_crypto_box_open(max_messagelength=256): """ max_messagelength: maximum length of the message, in bytes. i.e., the symbolic execution will not consider messages longer than max_messagelength """ proj = tweetnaclProject() state = funcEntryState( proj, "crypto_box_curve25519xsalsa20poly1305_tweet_open", [ ("m", pointerToUnconstrainedPublic() ), # Output parameter, will hold plaintext, length 'clen' ("c", pointerToUnconstrainedPublic()), # ciphertext: length 'clen' ("clen", publicValue()), # length of ciphertext. Not a pointer ("n", pointerTo(secretArray(24), 24)), # nonce, size crypto_box_NONCEBYTES ("pk", pointerTo( publicArray(32), 32)), # public key, size crypto_box_PUBLICKEYBYTES ("sk", pointerTo(secretArray(32), 32) ) # secret key, size crypto_box_SECRETKEYBYTES ]) state.add_constraints(getArgBVS(state, 'clen') <= max_messagelength) addDevURandom(state) return (proj, state)
def tweetnacl_crypto_sign_open(max_messagelength=256, with_hash_stub=True): """ note that this function *does not handle any secret inputs* so it probably isn't necessary to analyze. Still included for completeness. max_messagelength: maximum length of the message, in bytes. i.e., the symbolic execution will not consider messages longer than max_messagelength with_hash_stub: if True, then use a stub for the SHA512 hash function rather than trying to analyze it directly """ proj = tweetnaclProject() if with_hash_stub: addHashblocksStub(proj) state = funcEntryState( proj, "crypto_sign_ed25519_tweet_open", [ ("m", pointerToUnconstrainedPublic() ), # Output parameter: message, buffer of at least size 'smlen' ("mlen", pointerTo(publicValue(), 8) ), # Output parameter where the actual length of m is written ("sm", pointerToUnconstrainedPublic()), # Signed message: length 'smlen' ("smlen", publicValue() ), # signed message length: length of 'sm'. Not a pointer. ("pk", pointerTo(publicArray(32), 32) ) # public key: size crypto_sign_PUBLICKEYBYTES ]) state.add_constraints(getArgBVS(state, 'smlen') <= max_messagelength) addDevURandom(state) return (proj, state)
def tweetnacl_crypto_sign(max_messagelength=256, with_hash_stub=True): """ max_messagelength: maximum length of the message, in bytes. i.e., the symbolic execution will not consider messages longer than max_messagelength with_hash_stub: if True, then use a stub for the SHA512 hash function rather than trying to analyze it directly """ proj = tweetnaclProject() if with_hash_stub: addHashblocksStub(proj) state = funcEntryState( proj, "crypto_sign_ed25519_tweet", [ ( "sm", pointerToUnconstrainedPublic() ), # signed message: Output parameter, buffer of at least size [length m] + 64 ( "smlen", pointerTo(publicValue(), 8) ), # signed message length: Output parameter where the actual length of sm is written ("m", pointerToUnconstrainedPublic()), # message: unconstrained length ("mlen", publicValue()), # message length: length of m. Not a pointer. ("sk", pointerTo(secretArray(64), 64)), # secret key: size 64 bytes ]) state.add_constraints(getArgBVS(state, 'mlen') <= max_messagelength) addDevURandom(state) return (proj, state)
def tweetnacl_crypto_hash(max_messagelength=256, with_hashblocks_stub=True): """ note that this function *does not handle any secret inputs* so it probably isn't necessary to analyze. Still included for completeness, and because it is a building block of some of the other functions that might be useful to test alone. max_messagelength: maximum length of the message, in bytes. i.e., the symbolic execution will not consider messages longer than max_messagelength with_hash_stub: if True, then use a stub for the crypto_hashblocks function rather than trying to analyze it directly """ proj = tweetnaclProject() if with_hashblocks_stub: addHashblocksStub(proj) state = funcEntryState( proj, "crypto_hash_sha512_tweet", [ ("h", pointerTo( publicArray(64), 64)), # Output parameter: where to put the hash. 64 bytes. ("m", pointerToUnconstrainedPublic()), # message: length 'mlen' ("mlen", publicValue() ) # message length: length of m. Not a pointer. ]) state.add_constraints(getArgBVS(state, 'mlen') <= max_messagelength) addDevURandom(state) return (proj, state)
def abstractEVP_PKEY(engineNull=True): """ Abstract representation of an EVP_PKEY aka struct evp_pkey_st engineNull: if True, then the 'engine' field will be forced to NULL rather than unconstrained """ return struct([ publicValue(bits=32), # type publicValue(bits=32), # save_type publicValue( bits=64), # references (experimentally seems to be 64 bits?) pointerToUnconstrainedPublic(maxPointeeSize=36 * 8, cannotPointSecret=True), # ameth publicValue(0) if engineNull else pointerToUnconstrainedPublic( cannotPointSecret=True), # engine pointerToUnconstrainedPublic(cannotPointSecret=True), # pmeth_engine pointerTo( secretArray(512), 512 ), # pkey union. Conservatively estimated to definitely fit within 512 bytes publicValue(), # save_parameters pointerToUnconstrainedPublic(cannotPointSecret=True), # attributes pointerToUnconstrainedPublic(cannotPointSecret=True) # lock ])
def tweetnacl_crypto_secretbox(max_messagelength=256): """ max_messagelength: maximum length of the message, in bytes. i.e., the symbolic execution will not consider messages longer than max_messagelength """ proj = tweetnaclProject() state = funcEntryState( proj, "crypto_secretbox_xsalsa20poly1305_tweet", [ ("c", pointerToUnconstrainedPublic() ), # Output parameter, will hold ciphertext, length 'mlen' ("m", pointerToUnconstrainedPublic()), # message: length 'mlen' ("mlen", publicValue()), # length of message. Not a pointer ("n", pointerTo( secretArray(24), 24)), # nonce, buffer of size crypto_secretbox_NONCEBYTES ("k", pointerTo(secretArray(32), 32)) # secret key: size 32 bytes ]) state.add_constraints(getArgBVS(state, 'mlen') <= max_messagelength) addDevURandom(state) return (proj, state)
def kocher(s): """ Pass a string like "01" or "12" to get an angr project and state for that Kocher test case. """ proj = angr.Project('spectector-clang/' + s + '.o') funcname = "victim_function_v" + s if s == '10': state = funcEntryState(proj, funcname, [(None, publicValue()), (None, publicValue(bits=8))]) elif s == '12': state = funcEntryState(proj, funcname, [(None, publicValue()), (None, publicValue())]) elif s == '09': state = funcEntryState(proj, funcname, [(None, publicValue()), (None, pointerToUnconstrainedPublic())]) elif s == '15': state = funcEntryState(proj, funcname, [(None, pointerToUnconstrainedPublic())]) else: state = funcEntryState(proj, funcname, [(None, publicValue())]) return (proj, state)
def openssl_ASN1_item_sign(): proj = opensslProject() state = funcEntryState( proj, "ASN1_item_sign", [("it", pointerToUnconstrainedPublic()), ("algor1", pointerToUnconstrainedPublic()), ("algor2", pointerToUnconstrainedPublic()), ("signature", pointerToUnconstrainedPublic()), ("asn", pointerToUnconstrainedPublic()), ("pkey", pointerTo(abstractEVP_PKEY(), 128, cannotPointSecret=True)), ("type", pointerToUnconstrainedPublic())]) addDevURandom(state) addEVPStubs(proj) return (proj, state)
def tweetnacl_crypto_onetimeauth_verify(max_messagelength=256): """ max_messagelength: maximum length of the message, in bytes. i.e., the symbolic execution will not consider messages longer than max_messagelength """ proj = tweetnaclProject() state = funcEntryState( proj, "crypto_onetimeauth_poly1305_tweet_verify", [ ("a", pointerTo( publicArray(16), 16)), # authenticator, size crypto_onetimeauth_BYTES ("m", pointerToUnconstrainedPublic()), # message: unconstrained length ("mlen", publicValue()), # length of message. Not a pointer ("k", pointerTo(secretArray(32), 32)) # secret key: size 32 bytes ]) state.add_constraints(getArgBVS(state, 'mlen') <= max_messagelength) addDevURandom(state) return (proj, state)
def tweetnacl_crypto_stream_salsa20(max_outputbytes=128): """ crypto_stream_salsa20 produces a continuous stream of output. max_outputbytes: maximum value of the 'clen' parameter which determines the output size i.e., the symbolic execution will not consider values of 'clen' larger than max_outputbytes """ proj = tweetnaclProject() state = funcEntryState( proj, "crypto_stream_salsa20_tweet", [ ("c", pointerToUnconstrainedPublic() ), # Output parameter, buffer of size clen ("clen", publicValue()), # length of the 'c' output buffer ("n", pointerTo(secretArray(8), 8) ), # nonce, buffer of size crypto_stream_salsa20_tweet_NONCEBYTES ("k", pointerTo(secretArray(32), 32)) # secret key: size 32 bytes ]) state.add_constraints(getArgBVS(state, 'clen') <= max_outputbytes) addDevURandom(state) return (proj, state)
def c_mee(args, generating_fname=False): if generating_fname: return '' binary = 'fact-eval/c_mee.O3' declassified_load = 0x516c5f proj = angr.Project(binary) proj.hook_symbol("aesni_cbc_encrypt", AesStub()) aes_key_ks = [ [secretValue(bits=32) for _ in range(60)], # 0..ef publicValue(bits=32), # f0..f3 ] sha_ctx_head = [ [secretValue(bits=32) for _ in range(5)], # f4..107 publicValue(bits=32), # 108..10b publicValue(bits=32), # 10c..10f secretArray(64), # 110..14f publicValue(bits=32), # 150..153 ] sha_ctx_tail = [ [secretValue(bits=32) for _ in range(5)], # 154..167 publicValue(bits=32), # 168..16b publicValue(bits=32), # 16c..16f secretArray(64), # 170..1af publicValue(bits=32), # 1b0..1b3 ] sha_ctx_md = [ [secretValue(bits=32) for _ in range(5)], # 1b4 publicValue(bits=32), publicValue(bits=32), secretArray(64), publicValue(bits=32), ] evp_aes_hmac_sha1 = [ aes_key_ks, sha_ctx_head, sha_ctx_tail, sha_ctx_md, publicValue(bits=32), # [pad] 214..217 publicValue(13, bits=64), # 218..21f [publicValue(bits=8) for _ in range(16)], #[publicValue(bits=8) for _ in range(9)] + [publicValue(0x0302, bits=16), publicValue(bits=16)], secretArray(16), ] evp_cipher_ctx_st = [ pointerToUnconstrainedPublic(), # cipher pointerToUnconstrainedPublic(), # engine publicValue(0, bits=32), # encrypt publicValue(bits=32), # buf_len publicArray(16), # oiv publicArray(16), # iv publicArray(32), # buf publicValue(bits=32), # num publicValue(bits=32), # [padding] pointerToUnconstrainedPublic(), # app_data publicValue(bits=32), # key_len publicValue(bits=32), # [padding] publicValue(bits=64), # flags pointerTo(struct(evp_aes_hmac_sha1)), # cipher_data publicValue(bits=32), # final_used publicValue(bits=32), # block_mask publicArray(32), # final ] ctx = struct(evp_cipher_ctx_st) state = funcEntryState( proj, "aesni_cbc_hmac_sha1_cipher", [ ("ctx", pointerTo(ctx)), ("out", pointerTo(secretArray(1024), 1024)), # XXX should be unconstrained ("in", pointerTo(publicArray(1024), 1024)), # XXX should be unconstrained ("len", publicValue(1024, bits=64)), ]) return proj, state, "mee", [declassified_load], '00110010011001111011'