diff options
author | Nick Mathewson <nickm@torproject.org> | 2012-03-20 15:35:43 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2012-03-27 22:37:56 -0400 |
commit | de0dca0de76d9d50aeb5955fe3f435c6c190f8d7 (patch) | |
tree | 8d7005e768bc04ac1695b72cf3970d552570016f | |
parent | 00b4784575c88d5de15886b440096c1e2b9fb080 (diff) | |
download | tor-de0dca0de76d9d50aeb5955fe3f435c6c190f8d7.tar.gz tor-de0dca0de76d9d50aeb5955fe3f435c6c190f8d7.zip |
Refactor the API for setting up a block cipher.
It allows us more flexibility on the backend if the user needs to
specify the key and IV at setup time.
-rw-r--r-- | changes/crypto_api | 3 | ||||
-rw-r--r-- | src/common/aes.c | 16 | ||||
-rw-r--r-- | src/common/aes.h | 4 | ||||
-rw-r--r-- | src/common/crypto.c | 158 | ||||
-rw-r--r-- | src/common/crypto.h | 17 | ||||
-rw-r--r-- | src/or/circuitbuild.c | 4 | ||||
-rw-r--r-- | src/or/rendcommon.c | 13 | ||||
-rw-r--r-- | src/or/routerparse.c | 15 | ||||
-rw-r--r-- | src/test/bench.c | 17 | ||||
-rw-r--r-- | src/test/test_crypto.c | 135 |
10 files changed, 129 insertions, 253 deletions
diff --git a/changes/crypto_api b/changes/crypto_api new file mode 100644 index 0000000000..608999f47d --- /dev/null +++ b/changes/crypto_api @@ -0,0 +1,3 @@ + o Code refactoring: + - Change the symmetric cipher interface so that creating and + initializing a stream cipher are no longer separate functions. diff --git a/src/common/aes.c b/src/common/aes.c index cfd931fab1..3121891068 100644 --- a/src/common/aes.c +++ b/src/common/aes.c @@ -209,14 +209,22 @@ _aes_fill_buf(aes_cnt_cipher_t *cipher) } } +static void aes_set_key(aes_cnt_cipher_t *cipher, const char *key, + int key_bits); +static void aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv); + /** - * Return a newly allocated counter-mode AES128 cipher implementation. + * Return a newly allocated counter-mode AES128 cipher implementation, + * using the 128-bit key <b>key</b> and the 128-bit IV <b>iv</b>. */ aes_cnt_cipher_t* -aes_new_cipher(void) +aes_new_cipher(const char *key, const char *iv) { aes_cnt_cipher_t* result = tor_malloc_zero(sizeof(aes_cnt_cipher_t)); + aes_set_key(result, key, 128); + aes_set_iv(result, iv); + return result; } @@ -224,7 +232,7 @@ aes_new_cipher(void) * <b>key_bits</b> bits long (must be 128, 192, or 256). Also resets * the counter to 0. */ -void +static void aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits) { if (should_use_EVP) { @@ -398,7 +406,7 @@ aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len) /** Reset the 128-bit counter of <b>cipher</b> to the 16-bit big-endian value * in <b>iv</b>. */ -void +static void aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv) { #ifdef USING_COUNTER_VARS diff --git a/src/common/aes.h b/src/common/aes.h index f9de68a1bf..04b424ec77 100644 --- a/src/common/aes.h +++ b/src/common/aes.h @@ -16,13 +16,11 @@ struct aes_cnt_cipher; typedef struct aes_cnt_cipher aes_cnt_cipher_t; -aes_cnt_cipher_t* aes_new_cipher(void); +aes_cnt_cipher_t* aes_new_cipher(const char *key, const char *iv); void aes_cipher_free(aes_cnt_cipher_t *cipher); -void aes_set_key(aes_cnt_cipher_t *cipher, const char *key, int key_bits); void aes_crypt(aes_cnt_cipher_t *cipher, const char *input, size_t len, char *output); void aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len); -void aes_set_iv(aes_cnt_cipher_t *cipher, const char *iv); int evaluate_evp_for_aes(int force_value); int evaluate_ctr_for_aes(void); diff --git a/src/common/crypto.c b/src/common/crypto.c index 02f3d2fbba..2bd2e1e4d2 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -119,6 +119,7 @@ struct crypto_pk_t struct crypto_cipher_t { char key[CIPHER_KEY_LEN]; /**< The raw key. */ + char iv[CIPHER_IV_LEN]; /**< The initial IV. */ aes_cnt_cipher_t *cipher; /**< The key in format usable for counter-mode AES * encryption */ }; @@ -383,48 +384,37 @@ crypto_pk_free(crypto_pk_t *env) tor_free(env); } -/** Create a new symmetric cipher for a given key and encryption flag - * (1=encrypt, 0=decrypt). Return the crypto object on success; NULL - * on failure. +/** Allocate and return a new symmetric cipher using the provided key and iv. + * The key is CIPHER_KEY_LEN bytes; the IV is CIPHER_IV_LEN bytes. If you + * provide NULL in place of either one, it is generated at random. */ crypto_cipher_t * -crypto_create_init_cipher(const char *key, int encrypt_mode) +crypto_cipher_new_with_iv(const char *key, const char *iv) { - int r; - crypto_cipher_t *crypto = NULL; - - if (! (crypto = crypto_cipher_new())) { - log_warn(LD_CRYPTO, "Unable to allocate crypto object"); - return NULL; - } + crypto_cipher_t *env; - crypto_cipher_set_key(crypto, key); + env = tor_malloc_zero(sizeof(crypto_cipher_t)); - if (encrypt_mode) - r = crypto_cipher_encrypt_init_cipher(crypto); + if (key == NULL) + crypto_rand(env->key, CIPHER_KEY_LEN); + else + memcpy(env->key, key, CIPHER_KEY_LEN); + if (iv == NULL) + crypto_rand(env->iv, CIPHER_IV_LEN); else - r = crypto_cipher_decrypt_init_cipher(crypto); + memcpy(env->iv, iv, CIPHER_IV_LEN); - if (r) - goto error; - return crypto; + env->cipher = aes_new_cipher(env->key, env->iv); - error: - if (crypto) - crypto_cipher_free(crypto); - return NULL; + return env; } -/** Allocate and return a new symmetric cipher. - */ crypto_cipher_t * -crypto_cipher_new(void) +crypto_cipher_new(const char *key) { - crypto_cipher_t *env; - - env = tor_malloc_zero(sizeof(crypto_cipher_t)); - env->cipher = aes_new_cipher(); - return env; + char zeroiv[CIPHER_IV_LEN]; + memset(zeroiv, 0, sizeof(zeroiv)); + return crypto_cipher_new_with_iv(key, zeroiv); } /** Free a symmetric cipher. @@ -1043,12 +1033,8 @@ crypto_pk_public_hybrid_encrypt(crypto_pk_t *env, tor_assert(tolen >= fromlen + overhead + CIPHER_KEY_LEN); tor_assert(tolen >= pkeylen); - cipher = crypto_cipher_new(); - if (!cipher) return -1; - if (crypto_cipher_generate_key(cipher)<0) - goto err; - if (crypto_cipher_encrypt_init_cipher(cipher)<0) - goto err; + cipher = crypto_cipher_new(NULL); /* generate a new key. */ + buf = tor_malloc(pkeylen+1); memcpy(buf, cipher->key, CIPHER_KEY_LEN); memcpy(buf+CIPHER_KEY_LEN, from, pkeylen-overhead-CIPHER_KEY_LEN); @@ -1113,7 +1099,7 @@ crypto_pk_private_hybrid_decrypt(crypto_pk_t *env, "No room for a symmetric key"); goto err; } - cipher = crypto_create_init_cipher(buf, 0); + cipher = crypto_cipher_new(buf); if (!cipher) { goto err; } @@ -1301,49 +1287,6 @@ crypto_pk_check_fingerprint_syntax(const char *s) /* symmetric crypto */ -/** Generate a new random key for the symmetric cipher in <b>env</b>. - * Return 0 on success, -1 on failure. Does not initialize the cipher. - */ -int -crypto_cipher_generate_key(crypto_cipher_t *env) -{ - tor_assert(env); - - return crypto_rand(env->key, CIPHER_KEY_LEN); -} - -/** Set the symmetric key for the cipher in <b>env</b> to the first - * CIPHER_KEY_LEN bytes of <b>key</b>. Does not initialize the cipher. - */ -void -crypto_cipher_set_key(crypto_cipher_t *env, const char *key) -{ - tor_assert(env); - tor_assert(key); - - memcpy(env->key, key, CIPHER_KEY_LEN); -} - -/** Generate an initialization vector for our AES-CTR cipher; store it - * in the first CIPHER_IV_LEN bytes of <b>iv_out</b>. */ -void -crypto_cipher_generate_iv(char *iv_out) -{ - crypto_rand(iv_out, CIPHER_IV_LEN); -} - -/** Adjust the counter of <b>env</b> to point to the first byte of the block - * corresponding to the encryption of the CIPHER_IV_LEN bytes at - * <b>iv</b>. */ -int -crypto_cipher_set_iv(crypto_cipher_t *env, const char *iv) -{ - tor_assert(env); - tor_assert(iv); - aes_set_iv(env->cipher, iv); - return 0; -} - /** Return a pointer to the key set for the cipher in <b>env</b>. */ const char * @@ -1352,30 +1295,6 @@ crypto_cipher_get_key(crypto_cipher_t *env) return env->key; } -/** Initialize the cipher in <b>env</b> for encryption. Return 0 on - * success, -1 on failure. - */ -int -crypto_cipher_encrypt_init_cipher(crypto_cipher_t *env) -{ - tor_assert(env); - - aes_set_key(env->cipher, env->key, CIPHER_KEY_LEN*8); - return 0; -} - -/** Initialize the cipher in <b>env</b> for decryption. Return 0 on - * success, -1 on failure. - */ -int -crypto_cipher_decrypt_init_cipher(crypto_cipher_t *env) -{ - tor_assert(env); - - aes_set_key(env->cipher, env->key, CIPHER_KEY_LEN*8); - return 0; -} - /** Encrypt <b>fromlen</b> bytes from <b>from</b> using the cipher * <b>env</b>; on success, store the result to <b>to</b> and return 0. * On failure, return -1. @@ -1424,20 +1343,17 @@ crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *buf, size_t len) } /** Encrypt <b>fromlen</b> bytes (at least 1) from <b>from</b> with the key in - * <b>cipher</b> to the buffer in <b>to</b> of length + * <b>key</b> to the buffer in <b>to</b> of length * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> plus * CIPHER_IV_LEN bytes for the initialization vector. On success, return the * number of bytes written, on failure, return -1. - * - * This function adjusts the current position of the counter in <b>cipher</b> - * to immediately after the encrypted data. */ int -crypto_cipher_encrypt_with_iv(crypto_cipher_t *cipher, +crypto_cipher_encrypt_with_iv(const char *key, char *to, size_t tolen, const char *from, size_t fromlen) { - tor_assert(cipher); + crypto_cipher_t *cipher; tor_assert(from); tor_assert(to); tor_assert(fromlen < INT_MAX); @@ -1447,28 +1363,27 @@ crypto_cipher_encrypt_with_iv(crypto_cipher_t *cipher, if (tolen < fromlen + CIPHER_IV_LEN) return -1; - crypto_cipher_generate_iv(to); - if (crypto_cipher_set_iv(cipher, to)<0) - return -1; + cipher = crypto_cipher_new_with_iv(key, NULL); + + memcpy(to, cipher->iv, CIPHER_IV_LEN); crypto_cipher_encrypt(cipher, to+CIPHER_IV_LEN, from, fromlen); + crypto_cipher_free(cipher); return (int)(fromlen + CIPHER_IV_LEN); } /** Decrypt <b>fromlen</b> bytes (at least 1+CIPHER_IV_LEN) from <b>from</b> - * with the key in <b>cipher</b> to the buffer in <b>to</b> of length + * with the key in <b>key</b> to the buffer in <b>to</b> of length * <b>tolen</b>. <b>tolen</b> must be at least <b>fromlen</b> minus * CIPHER_IV_LEN bytes for the initialization vector. On success, return the * number of bytes written, on failure, return -1. - * - * This function adjusts the current position of the counter in <b>cipher</b> - * to immediately after the decrypted data. */ int -crypto_cipher_decrypt_with_iv(crypto_cipher_t *cipher, +crypto_cipher_decrypt_with_iv(const char *key, char *to, size_t tolen, const char *from, size_t fromlen) { - tor_assert(cipher); + crypto_cipher_t *cipher; + tor_assert(key); tor_assert(from); tor_assert(to); tor_assert(fromlen < INT_MAX); @@ -1478,9 +1393,10 @@ crypto_cipher_decrypt_with_iv(crypto_cipher_t *cipher, if (tolen < fromlen - CIPHER_IV_LEN) return -1; - if (crypto_cipher_set_iv(cipher, from)<0) - return -1; + cipher = crypto_cipher_new_with_iv(key, from); + crypto_cipher_encrypt(cipher, to, from+CIPHER_IV_LEN, fromlen-CIPHER_IV_LEN); + crypto_cipher_free(cipher); return (int)(fromlen - CIPHER_IV_LEN); } diff --git a/src/common/crypto.h b/src/common/crypto.h index 1c5ee0d23e..00ac26ba26 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -125,11 +125,8 @@ void crypto_pk_free(crypto_pk_t *env); void crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname); -/* convenience function: wraps crypto_cipher_new, set_key, and init. */ -crypto_cipher_t *crypto_create_init_cipher(const char *key, - int encrypt_mode); - -crypto_cipher_t *crypto_cipher_new(void); +crypto_cipher_t *crypto_cipher_new(const char *key); +crypto_cipher_t *crypto_cipher_new_with_iv(const char *key, const char *iv); void crypto_cipher_free(crypto_cipher_t *env); /* public key crypto */ @@ -189,13 +186,7 @@ int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space); int crypto_pk_check_fingerprint_syntax(const char *s); /* symmetric crypto */ -int crypto_cipher_generate_key(crypto_cipher_t *env); -void crypto_cipher_set_key(crypto_cipher_t *env, const char *key); -void crypto_cipher_generate_iv(char *iv_out); -int crypto_cipher_set_iv(crypto_cipher_t *env, const char *iv); const char *crypto_cipher_get_key(crypto_cipher_t *env); -int crypto_cipher_encrypt_init_cipher(crypto_cipher_t *env); -int crypto_cipher_decrypt_init_cipher(crypto_cipher_t *env); int crypto_cipher_encrypt(crypto_cipher_t *env, char *to, const char *from, size_t fromlen); @@ -203,10 +194,10 @@ int crypto_cipher_decrypt(crypto_cipher_t *env, char *to, const char *from, size_t fromlen); int crypto_cipher_crypt_inplace(crypto_cipher_t *env, char *d, size_t len); -int crypto_cipher_encrypt_with_iv(crypto_cipher_t *env, +int crypto_cipher_encrypt_with_iv(const char *key, char *to, size_t tolen, const char *from, size_t fromlen); -int crypto_cipher_decrypt_with_iv(crypto_cipher_t *env, +int crypto_cipher_decrypt_with_iv(const char *key, char *to, size_t tolen, const char *from, size_t fromlen); diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 3948008775..1c7367a3fc 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -2334,12 +2334,12 @@ circuit_init_cpath_crypto(crypt_path_t *cpath, const char *key_data, crypto_digest_add_bytes(cpath->b_digest, key_data+DIGEST_LEN, DIGEST_LEN); if (!(cpath->f_crypto = - crypto_create_init_cipher(key_data+(2*DIGEST_LEN),1))) { + crypto_cipher_new(key_data+(2*DIGEST_LEN)))) { log_warn(LD_BUG,"Forward cipher initialization failed."); return -1; } if (!(cpath->b_crypto = - crypto_create_init_cipher(key_data+(2*DIGEST_LEN)+CIPHER_KEY_LEN,0))) { + crypto_cipher_new(key_data+(2*DIGEST_LEN)+CIPHER_KEY_LEN))) { log_warn(LD_BUG,"Backward cipher initialization failed."); return -1; } diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index 9c7bf518d1..20bbdafec9 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -290,11 +290,10 @@ rend_encrypt_v2_intro_points_basic(char **encrypted_out, enc[1] = (uint8_t)client_blocks; /* Encrypt with random session key. */ - cipher = crypto_create_init_cipher(session_key, 1); - enclen = crypto_cipher_encrypt_with_iv(cipher, + enclen = crypto_cipher_encrypt_with_iv(session_key, enc + 2 + client_entries_len, CIPHER_IV_LEN + strlen(encoded), encoded, strlen(encoded)); - crypto_cipher_free(cipher); + if (enclen < 0) { log_warn(LD_REND, "Could not encrypt introduction point string."); goto done; @@ -307,7 +306,7 @@ rend_encrypt_v2_intro_points_basic(char **encrypted_out, SMARTLIST_FOREACH_BEGIN(client_cookies, const char *, cookie) { client_part = tor_malloc_zero(REND_BASIC_AUTH_CLIENT_ENTRY_LEN); /* Encrypt session key. */ - cipher = crypto_create_init_cipher(cookie, 1); + cipher = crypto_cipher_new(cookie); if (crypto_cipher_encrypt(cipher, client_part + REND_BASIC_AUTH_CLIENT_ID_LEN, session_key, CIPHER_KEY_LEN) < 0) { @@ -374,18 +373,16 @@ rend_encrypt_v2_intro_points_stealth(char **encrypted_out, const char *descriptor_cookie) { int r = -1, enclen; - crypto_cipher_t *cipher; char *enc; tor_assert(encoded); tor_assert(descriptor_cookie); enc = tor_malloc_zero(1 + CIPHER_IV_LEN + strlen(encoded)); enc[0] = 0x02; /* Auth type */ - cipher = crypto_create_init_cipher(descriptor_cookie, 1); - enclen = crypto_cipher_encrypt_with_iv(cipher, enc + 1, + enclen = crypto_cipher_encrypt_with_iv(descriptor_cookie, + enc + 1, CIPHER_IV_LEN+strlen(encoded), encoded, strlen(encoded)); - crypto_cipher_free(cipher); if (enclen < 0) { log_warn(LD_REND, "Could not encrypt introduction point string."); goto done; diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 95cef93521..0aae0aa949 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -4887,7 +4887,7 @@ rend_decrypt_introduction_points(char **ipos_decrypted, if (tor_memeq(ipos_encrypted + pos, client_id, REND_BASIC_AUTH_CLIENT_ID_LEN)) { /* Attempt to decrypt introduction points. */ - cipher = crypto_create_init_cipher(descriptor_cookie, 0); + cipher = crypto_cipher_new(descriptor_cookie); if (crypto_cipher_decrypt(cipher, session_key, ipos_encrypted + pos + REND_BASIC_AUTH_CLIENT_ID_LEN, CIPHER_KEY_LEN) < 0) { @@ -4896,13 +4896,13 @@ rend_decrypt_introduction_points(char **ipos_decrypted, return -1; } crypto_cipher_free(cipher); - cipher = crypto_create_init_cipher(session_key, 0); + len = ipos_encrypted_size - 2 - client_entries_len - CIPHER_IV_LEN; dec = tor_malloc(len); - declen = crypto_cipher_decrypt_with_iv(cipher, dec, len, + declen = crypto_cipher_decrypt_with_iv(session_key, dec, len, ipos_encrypted + 2 + client_entries_len, ipos_encrypted_size - 2 - client_entries_len); - crypto_cipher_free(cipher); + if (declen < 0) { log_warn(LD_REND, "Could not decrypt introduction point string."); tor_free(dec); @@ -4923,7 +4923,6 @@ rend_decrypt_introduction_points(char **ipos_decrypted, "check your authorization for this service!"); return -1; } else if (ipos_encrypted[0] == (int)REND_STEALTH_AUTH) { - crypto_cipher_t *cipher; char *dec; int declen; if (ipos_encrypted_size < CIPHER_IV_LEN + 2) { @@ -4932,13 +4931,13 @@ rend_decrypt_introduction_points(char **ipos_decrypted, return -1; } dec = tor_malloc_zero(ipos_encrypted_size - CIPHER_IV_LEN - 1); - cipher = crypto_create_init_cipher(descriptor_cookie, 0); - declen = crypto_cipher_decrypt_with_iv(cipher, dec, + + declen = crypto_cipher_decrypt_with_iv(descriptor_cookie, dec, ipos_encrypted_size - CIPHER_IV_LEN - 1, ipos_encrypted + 1, ipos_encrypted_size - 1); - crypto_cipher_free(cipher); + if (declen < 0) { log_warn(LD_REND, "Decrypting introduction points failed!"); tor_free(dec); diff --git a/src/test/bench.c b/src/test/bench.c index a662bd23e8..3081814802 100644 --- a/src/test/bench.c +++ b/src/test/bench.c @@ -77,9 +77,8 @@ bench_aes(void) uint64_t start, end; const int bytes_per_iter = (1<<24); reset_perftime(); - c = crypto_cipher_new(); - crypto_cipher_generate_key(c); - crypto_cipher_encrypt_init_cipher(c); + c = crypto_cipher_new(NULL); + for (len = 1; len <= 8192; len *= 2) { int iters = bytes_per_iter / len; b1 = tor_malloc_zero(len); @@ -108,9 +107,7 @@ bench_cell_aes(void) crypto_cipher_t *c; int i, misalign; - c = crypto_cipher_new(); - crypto_cipher_generate_key(c); - crypto_cipher_encrypt_init_cipher(c); + c = crypto_cipher_new(NULL); reset_perftime(); for (misalign = 0; misalign <= max_misalign; ++misalign) { @@ -221,12 +218,8 @@ bench_cell_ops(void) or_circ->_base.purpose = CIRCUIT_PURPOSE_OR; /* Initialize crypto */ - or_circ->p_crypto = crypto_cipher_new(); - crypto_cipher_generate_key(or_circ->p_crypto); - crypto_cipher_encrypt_init_cipher(or_circ->p_crypto); - or_circ->n_crypto = crypto_cipher_new(); - crypto_cipher_generate_key(or_circ->n_crypto); - crypto_cipher_encrypt_init_cipher(or_circ->n_crypto); + or_circ->p_crypto = crypto_cipher_new(NULL); + or_circ->n_crypto = crypto_cipher_new(NULL); or_circ->p_digest = crypto_digest_new(); or_circ->n_digest = crypto_digest_new(); diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index 3f9029a8f8..95a33613af 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -118,14 +118,10 @@ test_crypto_aes(void *arg) memset(data2, 0, 1024); memset(data3, 0, 1024); - env1 = crypto_cipher_new(); + env1 = crypto_cipher_new(NULL); test_neq(env1, 0); - env2 = crypto_cipher_new(); + env2 = crypto_cipher_new(crypto_cipher_get_key(env1)); test_neq(env2, 0); - j = crypto_cipher_generate_key(env1); - crypto_cipher_set_key(env2, crypto_cipher_get_key(env1)); - crypto_cipher_encrypt_init_cipher(env1); - crypto_cipher_decrypt_init_cipher(env2); /* Try encrypting 512 chars. */ crypto_cipher_encrypt(env1, data2, data1, 512); @@ -155,10 +151,8 @@ test_crypto_aes(void *arg) env2 = NULL; memset(data3, 0, 1024); - env2 = crypto_cipher_new(); + env2 = crypto_cipher_new(crypto_cipher_get_key(env1)); test_neq(env2, 0); - crypto_cipher_set_key(env2, crypto_cipher_get_key(env1)); - crypto_cipher_encrypt_init_cipher(env2); for (j = 0; j < 1024-16; j += 17) { crypto_cipher_encrypt(env2, data3+j, data1+j, 17); } @@ -174,10 +168,9 @@ test_crypto_aes(void *arg) env2 = NULL; /* NIST test vector for aes. */ - env1 = crypto_cipher_new(); /* IV starts at 0 */ - crypto_cipher_set_key(env1, "\x80\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00"); - crypto_cipher_encrypt_init_cipher(env1); + /* IV starts at 0 */ + env1 = crypto_cipher_new("\x80\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00"); crypto_cipher_encrypt(env1, data1, "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00", 16); @@ -185,37 +178,55 @@ test_crypto_aes(void *arg) /* Now test rollover. All these values are originally from a python * script. */ - crypto_cipher_set_iv(env1, "\x00\x00\x00\x00\x00\x00\x00\x00" - "\xff\xff\xff\xff\xff\xff\xff\xff"); + crypto_cipher_free(env1); + env1 = crypto_cipher_new_with_iv( + "\x80\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00" + "\xff\xff\xff\xff\xff\xff\xff\xff"); memset(data2, 0, 1024); crypto_cipher_encrypt(env1, data1, data2, 32); test_memeq_hex(data1, "335fe6da56f843199066c14a00a40231" "cdd0b917dbc7186908a6bfb5ffd574d3"); - - crypto_cipher_set_iv(env1, "\x00\x00\x00\x00\xff\xff\xff\xff" - "\xff\xff\xff\xff\xff\xff\xff\xff"); + crypto_cipher_free(env1); + env1 = crypto_cipher_new_with_iv( + "\x80\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff"); memset(data2, 0, 1024); crypto_cipher_encrypt(env1, data1, data2, 32); test_memeq_hex(data1, "e627c6423fa2d77832a02b2794094b73" "3e63c721df790d2c6469cc1953a3ffac"); - - crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff" - "\xff\xff\xff\xff\xff\xff\xff\xff"); + crypto_cipher_free(env1); + env1 = crypto_cipher_new_with_iv( + "\x80\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff"); memset(data2, 0, 1024); crypto_cipher_encrypt(env1, data1, data2, 32); test_memeq_hex(data1, "2aed2bff0de54f9328efd070bf48f70a" "0EDD33D3C621E546455BD8BA1418BEC8"); /* Now check rollover on inplace cipher. */ - crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff" - "\xff\xff\xff\xff\xff\xff\xff\xff"); + crypto_cipher_free(env1); + env1 = crypto_cipher_new_with_iv( + "\x80\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff"); crypto_cipher_crypt_inplace(env1, data2, 64); test_memeq_hex(data2, "2aed2bff0de54f9328efd070bf48f70a" "0EDD33D3C621E546455BD8BA1418BEC8" "93e2c5243d6839eac58503919192f7ae" "1908e67cafa08d508816659c2e693191"); - crypto_cipher_set_iv(env1, "\xff\xff\xff\xff\xff\xff\xff\xff" - "\xff\xff\xff\xff\xff\xff\xff\xff"); + crypto_cipher_free(env1); + env1 = crypto_cipher_new_with_iv( + "\x80\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00", + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff"); crypto_cipher_crypt_inplace(env1, data2, 64); test_assert(tor_mem_is_zero(data2, 64)); @@ -674,7 +685,6 @@ test_crypto_s2k(void) static void test_crypto_aes_iv(void *arg) { - crypto_cipher_t *cipher; char *plain, *encrypted1, *encrypted2, *decrypted1, *decrypted2; char plain_1[1], plain_15[15], plain_16[16], plain_17[17]; char key1[16], key2[16]; @@ -698,113 +708,76 @@ test_crypto_aes_iv(void *arg) crypto_rand(plain_17, 17); key1[0] = key2[0] + 128; /* Make sure that contents are different. */ /* Encrypt and decrypt with the same key. */ - cipher = crypto_create_init_cipher(key1, 1); - encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 4095, + encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 4095, plain, 4095); - crypto_cipher_free(cipher); - cipher = NULL; + test_eq(encrypted_size, 16 + 4095); tt_assert(encrypted_size > 0); /* This is obviously true, since 4111 is * greater than 0, but its truth is not * obvious to all analysis tools. */ - cipher = crypto_create_init_cipher(key1, 0); - decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095, + decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 4095, encrypted1, encrypted_size); - crypto_cipher_free(cipher); - cipher = NULL; + test_eq(decrypted_size, 4095); tt_assert(decrypted_size > 0); test_memeq(plain, decrypted1, 4095); /* Encrypt a second time (with a new random initialization vector). */ - cipher = crypto_create_init_cipher(key1, 1); - encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted2, 16 + 4095, + encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted2, 16 + 4095, plain, 4095); - crypto_cipher_free(cipher); - cipher = NULL; + test_eq(encrypted_size, 16 + 4095); tt_assert(encrypted_size > 0); - cipher = crypto_create_init_cipher(key1, 0); - decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095, + decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted2, 4095, encrypted2, encrypted_size); - crypto_cipher_free(cipher); - cipher = NULL; test_eq(decrypted_size, 4095); tt_assert(decrypted_size > 0); test_memeq(plain, decrypted2, 4095); test_memneq(encrypted1, encrypted2, encrypted_size); /* Decrypt with the wrong key. */ - cipher = crypto_create_init_cipher(key2, 0); - decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted2, 4095, + decrypted_size = crypto_cipher_decrypt_with_iv(key2, decrypted2, 4095, encrypted1, encrypted_size); - crypto_cipher_free(cipher); - cipher = NULL; test_memneq(plain, decrypted2, encrypted_size); /* Alter the initialization vector. */ encrypted1[0] += 42; - cipher = crypto_create_init_cipher(key1, 0); - decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 4095, + decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 4095, encrypted1, encrypted_size); - crypto_cipher_free(cipher); - cipher = NULL; test_memneq(plain, decrypted2, 4095); /* Special length case: 1. */ - cipher = crypto_create_init_cipher(key1, 1); - encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 1, + encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 1, plain_1, 1); - crypto_cipher_free(cipher); - cipher = NULL; test_eq(encrypted_size, 16 + 1); tt_assert(encrypted_size > 0); - cipher = crypto_create_init_cipher(key1, 0); - decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 1, + decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 1, encrypted1, encrypted_size); - crypto_cipher_free(cipher); - cipher = NULL; test_eq(decrypted_size, 1); tt_assert(decrypted_size > 0); test_memeq(plain_1, decrypted1, 1); /* Special length case: 15. */ - cipher = crypto_create_init_cipher(key1, 1); - encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 15, + encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 15, plain_15, 15); - crypto_cipher_free(cipher); - cipher = NULL; test_eq(encrypted_size, 16 + 15); tt_assert(encrypted_size > 0); - cipher = crypto_create_init_cipher(key1, 0); - decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 15, + decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 15, encrypted1, encrypted_size); - crypto_cipher_free(cipher); - cipher = NULL; test_eq(decrypted_size, 15); tt_assert(decrypted_size > 0); test_memeq(plain_15, decrypted1, 15); /* Special length case: 16. */ - cipher = crypto_create_init_cipher(key1, 1); - encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 16, + encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 16, plain_16, 16); - crypto_cipher_free(cipher); - cipher = NULL; test_eq(encrypted_size, 16 + 16); tt_assert(encrypted_size > 0); - cipher = crypto_create_init_cipher(key1, 0); - decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 16, + decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 16, encrypted1, encrypted_size); - crypto_cipher_free(cipher); - cipher = NULL; test_eq(decrypted_size, 16); tt_assert(decrypted_size > 0); test_memeq(plain_16, decrypted1, 16); /* Special length case: 17. */ - cipher = crypto_create_init_cipher(key1, 1); - encrypted_size = crypto_cipher_encrypt_with_iv(cipher, encrypted1, 16 + 17, + encrypted_size = crypto_cipher_encrypt_with_iv(key1, encrypted1, 16 + 17, plain_17, 17); - crypto_cipher_free(cipher); - cipher = NULL; test_eq(encrypted_size, 16 + 17); tt_assert(encrypted_size > 0); - cipher = crypto_create_init_cipher(key1, 0); - decrypted_size = crypto_cipher_decrypt_with_iv(cipher, decrypted1, 17, + decrypted_size = crypto_cipher_decrypt_with_iv(key1, decrypted1, 17, encrypted1, encrypted_size); test_eq(decrypted_size, 17); tt_assert(decrypted_size > 0); @@ -817,8 +790,6 @@ test_crypto_aes_iv(void *arg) tor_free(encrypted2); tor_free(decrypted1); tor_free(decrypted2); - if (cipher) - crypto_cipher_free(cipher); } /** Test base32 decoding. */ |