err_status_t aes_test_inverse(void) { v128_t x, y; aes_expanded_key_t expanded_key, decrypt_key; uint8_t plaintext[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; uint8_t key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; v128_t k; v128_set_to_zero(&x); v128_copy_octet_string(&k, key); v128_copy_octet_string(&x, plaintext); aes_expand_encryption_key(k, expanded_key); aes_expand_decryption_key(k, decrypt_key); aes_encrypt(&x, expanded_key); aes_decrypt(&x, decrypt_key); /* compare to expected value then report */ v128_copy_octet_string(&y, plaintext); if (v128_is_eq(&x, &y)) return err_status_ok; return err_status_algo_fail; }
err_status_t aes_icm_context_init(aes_icm_ctx_t *c, const octet_t *key) { v128_t tmp_key; /* set counter and initial values to 'offset' value */ /* FIX!!! this assumes the salt is at key + 16, and thus that the */ /* FIX!!! cipher key length is 16! Also note this copies past the end of the 'key' array by 2 bytes! */ v128_copy_octet_string(&c->counter, key + 16); v128_copy_octet_string(&c->offset, key + 16); /* force last two octets of the offset to zero (for srtp compatibility) */ c->offset.octet[14] = c->offset.octet[15] = 0; c->counter.octet[14] = c->counter.octet[15] = 0; /* set tmp_key (for alignment) */ v128_copy_octet_string(&tmp_key, key); debug_print(mod_aes_icm, "key: %s", v128_hex_string(&tmp_key)); debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); /* expand key */ aes_expand_encryption_key(tmp_key, c->expanded_key); /* indicate that the keystream_buffer is empty */ c->bytes_in_buffer = 0; return err_status_ok; }
/* * aes_icm_openssl_context_init(...) initializes the aes_icm_context * using the value in key[]. * * the key is the secret key * * the salt is unpredictable (but not necessarily secret) data which * randomizes the starting point in the keystream */ err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key) { /* set counter and initial values to 'offset' value */ /* FIX!!! this assumes the salt is at key + 16, and thus that the */ /* FIX!!! cipher key length is 16! Also note this copies past the end of the 'key' array by 2 bytes! */ v128_copy_octet_string(&c->counter, key + c->key_size); v128_copy_octet_string(&c->offset, key + c->key_size); /* force last two octets of the offset to zero (for srtp compatibility) */ c->offset.v8[SALT_SIZE] = c->offset.v8[SALT_SIZE + 1] = 0; c->counter.v8[SALT_SIZE] = c->counter.v8[SALT_SIZE + 1] = 0; /* copy key to be used later when CiscoSSL crypto context is created */ v128_copy_octet_string((v128_t*)&c->key, key); /* if the key is greater than 16 bytes, copy the second * half. Note, we treat AES-192 and AES-256 the same here * for simplicity. The storage location receiving the * key is statically allocated to handle a full 32 byte key * regardless of the cipher in use. */ if (c->key_size == AES_256_KEYSIZE || c->key_size == AES_192_KEYSIZE) { debug_print(mod_aes_icm, "Copying last 16 bytes of key: %s", v128_hex_string((v128_t*)(key + AES_128_KEYSIZE))); v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, key + AES_128_KEYSIZE); } debug_print(mod_aes_icm, "key: %s", v128_hex_string((v128_t*)&c->key)); debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); EVP_CIPHER_CTX_cleanup(&c->ctx); return err_status_ok; }
err_status_t aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, cipher_direction_t dir) { v128_t tmp_key; /* set tmp_key (for alignment) */ v128_copy_octet_string(&tmp_key, key); debug_print(mod_aes_cbc, "key: %s", v128_hex_string(&tmp_key)); /* expand key for the appropriate direction */ switch (dir) { case (direction_encrypt): aes_expand_encryption_key(&tmp_key, c->expanded_key); break; case (direction_decrypt): aes_expand_decryption_key(&tmp_key, c->expanded_key); break; default: return err_status_bad_param; } return err_status_ok; }
/* * aes_icm_openssl_context_init(...) initializes the aes_icm_context * using the value in key[]. * * the key is the secret key * * the salt is unpredictable (but not necessarily secret) data which * randomizes the starting point in the keystream */ err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key, int len) { /* * set counter and initial values to 'offset' value, being careful not to * go past the end of the key buffer */ if (c->key_size + SALT_SIZE != len) return err_status_bad_param; v128_set_to_zero(&c->counter); v128_set_to_zero(&c->offset); memcpy(&c->counter, key + c->key_size, SALT_SIZE); memcpy(&c->offset, key + c->key_size, SALT_SIZE); /* force last two octets of the offset to zero (for srtp compatibility) */ c->offset.v8[SALT_SIZE] = c->offset.v8[SALT_SIZE + 1] = 0; c->counter.v8[SALT_SIZE] = c->counter.v8[SALT_SIZE + 1] = 0; /* copy key to be used later when CiscoSSL crypto context is created */ v128_copy_octet_string((v128_t*)&c->key, key); /* if the key is greater than 16 bytes, copy the second * half. Note, we treat AES-192 and AES-256 the same here * for simplicity. The storage location receiving the * key is statically allocated to handle a full 32 byte key * regardless of the cipher in use. */ if (c->key_size == AES_256_KEYSIZE #ifndef BORINGSSL || c->key_size == AES_192_KEYSIZE #endif ) { debug_print(mod_aes_icm, "Copying last 16 bytes of key: %s", v128_hex_string((v128_t*)(key + AES_128_KEYSIZE))); v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, key + AES_128_KEYSIZE); } debug_print(mod_aes_icm, "key: %s", v128_hex_string((v128_t*)&c->key)); debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); EVP_CIPHER_CTX_cleanup(&c->ctx); return err_status_ok; }
/* * aes_gcm_openssl_context_init(...) initializes the aes_gcm_context * using the value in key[]. * * the key is the secret key */ err_status_t aes_gcm_openssl_context_init (aes_gcm_ctx_t *c, const uint8_t *key) { c->dir = direction_any; /* copy key to be used later when CiscoSSL crypto context is created */ v128_copy_octet_string((v128_t*)&c->key, key); if (c->key_size == AES_256_KEYSIZE) { debug_print(mod_aes_gcm, "Copying last 16 bytes of key: %s", v128_hex_string((v128_t*)(key + AES_128_KEYSIZE))); v128_copy_octet_string(((v128_t*)(&c->key.v8)) + 1, key + AES_128_KEYSIZE); } debug_print(mod_aes_gcm, "key: %s", v128_hex_string((v128_t*)&c->key)); EVP_CIPHER_CTX_cleanup(&c->ctx); return (err_status_ok); }
static srtp_err_status_t srtp_aes_icm_set_iv (srtp_aes_icm_ctx_t *c, uint8_t *iv, int direction) { v128_t nonce; /* set nonce (for alignment) */ v128_copy_octet_string(&nonce, iv); debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce)); v128_xor(&c->counter, &c->offset, &nonce); debug_print(srtp_mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter)); /* indicate that the keystream_buffer is empty */ c->bytes_in_buffer = 0; return srtp_err_status_ok; }
/* * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with * the offset */ static srtp_err_status_t srtp_aes_icm_openssl_set_iv (void *cv, uint8_t *iv, srtp_cipher_direction_t dir) { srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv; v128_t nonce; /* set nonce (for alignment) */ v128_copy_octet_string(&nonce, iv); debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce)); v128_xor(&c->counter, &c->offset, &nonce); debug_print(srtp_mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter)); if (!EVP_EncryptInit_ex(c->ctx, NULL, NULL, NULL, c->counter.v8)) { return srtp_err_status_fail; } else { return srtp_err_status_ok; } }
/* * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with * the offset */ err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, void *iv, int dir) { const EVP_CIPHER *evp; v128_t nonce; /* set nonce (for alignment) */ v128_copy_octet_string(&nonce, iv); debug_print(mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce)); v128_xor(&c->counter, &c->offset, &nonce); debug_print(mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter)); switch (c->key_size) { case AES_256_KEYSIZE: evp = EVP_aes_256_ctr(); break; #ifndef BORINGSSL case AES_192_KEYSIZE: evp = EVP_aes_192_ctr(); break; #endif case AES_128_KEYSIZE: evp = EVP_aes_128_ctr(); break; default: return err_status_bad_param; break; } if (!EVP_EncryptInit_ex(&c->ctx, evp, NULL, c->key.v8, c->counter.v8)) { return err_status_fail; } else { return err_status_ok; } }