From eb9b0a214bea919afb50b54ea437f013cbf427f1 Mon Sep 17 00:00:00 2001 From: Packit Date: Sep 15 2020 11:13:21 +0000 Subject: Apply patch 0001-Changes-for-OpenSSL-1.1.0-compatibility.patch patch_name: 0001-Changes-for-OpenSSL-1.1.0-compatibility.patch present_in_specfile: true --- diff --git a/crypto/cipher/aes_gcm_ossl.c b/crypto/cipher/aes_gcm_ossl.c index dce2a33..943dbd5 100644 --- a/crypto/cipher/aes_gcm_ossl.c +++ b/crypto/cipher/aes_gcm_ossl.c @@ -116,6 +116,13 @@ err_status_t aes_gcm_openssl_alloc (cipher_t **c, int key_len, int tlen) (*c)->state = allptr + sizeof(cipher_t); gcm = (aes_gcm_ctx_t *)(*c)->state; + gcm->ctx = EVP_CIPHER_CTX_new(); + if (gcm->ctx == NULL) { + crypto_free(*c); + *c = NULL; + return (err_status_alloc_fail); + } + /* increment ref_count */ switch (key_len) { case AES_128_GCM_KEYSIZE_WSALT: @@ -136,7 +143,6 @@ err_status_t aes_gcm_openssl_alloc (cipher_t **c, int key_len, int tlen) /* set key size */ (*c)->key_len = key_len; - EVP_CIPHER_CTX_init(&gcm->ctx); return (err_status_ok); } @@ -151,7 +157,7 @@ err_status_t aes_gcm_openssl_dealloc (cipher_t *c) ctx = (aes_gcm_ctx_t*)c->state; if (ctx) { - EVP_CIPHER_CTX_cleanup(&ctx->ctx); + EVP_CIPHER_CTX_free(ctx->ctx); /* decrement ref_count for the appropriate engine */ switch (ctx->key_size) { case AES_256_KEYSIZE: @@ -197,7 +203,7 @@ err_status_t aes_gcm_openssl_context_init (aes_gcm_ctx_t *c, const uint8_t *key) debug_print(mod_aes_gcm, "key: %s", v128_hex_string((v128_t*)&c->key)); - EVP_CIPHER_CTX_cleanup(&c->ctx); + EVP_CIPHER_CTX_cleanup(c->ctx); return (err_status_ok); } @@ -231,19 +237,19 @@ err_status_t aes_gcm_openssl_set_iv (aes_gcm_ctx_t *c, void *iv, break; } - if (!EVP_CipherInit_ex(&c->ctx, evp, NULL, (const unsigned char*)&c->key.v8, + if (!EVP_CipherInit_ex(c->ctx, evp, NULL, (const unsigned char*)&c->key.v8, NULL, (c->dir == direction_encrypt ? 1 : 0))) { return (err_status_init_fail); } /* set IV len and the IV value, the followiong 3 calls are required */ - if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) { + if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) { return (err_status_init_fail); } - if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) { + if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) { return (err_status_init_fail); } - if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) { + if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) { return (err_status_init_fail); } @@ -267,9 +273,9 @@ err_status_t aes_gcm_openssl_set_aad (aes_gcm_ctx_t *c, unsigned char *aad, * Set dummy tag, OpenSSL requires the Tag to be set before * processing AAD */ - EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, aad); + EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, aad); - rv = EVP_Cipher(&c->ctx, NULL, aad, aad_len); + rv = EVP_Cipher(c->ctx, NULL, aad, aad_len); if (rv != aad_len) { return (err_status_algo_fail); } else { @@ -295,7 +301,7 @@ err_status_t aes_gcm_openssl_encrypt (aes_gcm_ctx_t *c, unsigned char *buf, /* * Encrypt the data */ - EVP_Cipher(&c->ctx, buf, buf, *enc_len); + EVP_Cipher(c->ctx, buf, buf, *enc_len); return (err_status_ok); } @@ -317,12 +323,12 @@ err_status_t aes_gcm_openssl_get_tag (aes_gcm_ctx_t *c, unsigned char *buf, /* * Calculate the tag */ - EVP_Cipher(&c->ctx, NULL, NULL, 0); + EVP_Cipher(c->ctx, NULL, NULL, 0); /* * Retreive the tag */ - EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf); + EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf); /* * Increase encryption length by desired tag size @@ -351,14 +357,14 @@ err_status_t aes_gcm_openssl_decrypt (aes_gcm_ctx_t *c, unsigned char *buf, /* * Set the tag before decrypting */ - EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, + EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, buf + (*enc_len - c->tag_len)); - EVP_Cipher(&c->ctx, buf, buf, *enc_len - c->tag_len); + EVP_Cipher(c->ctx, buf, buf, *enc_len - c->tag_len); /* * Check the tag */ - if (EVP_Cipher(&c->ctx, NULL, NULL, 0)) { + if (EVP_Cipher(c->ctx, NULL, NULL, 0)) { return (err_status_auth_fail); } diff --git a/crypto/cipher/aes_gcm_ossl.c.4 b/crypto/cipher/aes_gcm_ossl.c.4 new file mode 100644 index 0000000..dce2a33 --- /dev/null +++ b/crypto/cipher/aes_gcm_ossl.c.4 @@ -0,0 +1,570 @@ +/* + * aes_gcm_ossl.c + * + * AES Galois Counter Mode + * + * John A. Foley + * Cisco Systems, Inc. + * + */ + +/* + * + * Copyright (c) 2013, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include "aes_icm_ossl.h" +#include "aes_gcm_ossl.h" +#include "alloc.h" +#include "crypto_types.h" + + +debug_module_t mod_aes_gcm = { + 0, /* debugging is off by default */ + "aes gcm" /* printable module name */ +}; + +/* + * The following are the global singleton instances for the + * 128-bit and 256-bit GCM ciphers. + */ +extern cipher_type_t aes_gcm_128_openssl; +extern cipher_type_t aes_gcm_256_openssl; + +/* + * For now we only support 8 and 16 octet tags. The spec allows for + * optional 12 byte tag, which may be supported in the future. + */ +#define GCM_AUTH_TAG_LEN 16 +#define GCM_AUTH_TAG_LEN_8 8 + + +/* + * This function allocates a new instance of this crypto engine. + * The key_len parameter should be one of 28 or 44 for + * AES-128-GCM or AES-256-GCM respectively. Note that the + * key length includes the 14 byte salt value that is used when + * initializing the KDF. + */ +err_status_t aes_gcm_openssl_alloc (cipher_t **c, int key_len, int tlen) +{ + aes_gcm_ctx_t *gcm; + int tmp; + uint8_t *allptr; + + debug_print(mod_aes_gcm, "allocating cipher with key length %d", key_len); + debug_print(mod_aes_gcm, "allocating cipher with tag length %d", tlen); + + /* + * Verify the key_len is valid for one of: AES-128/256 + */ + if (key_len != AES_128_GCM_KEYSIZE_WSALT && + key_len != AES_256_GCM_KEYSIZE_WSALT) { + return (err_status_bad_param); + } + + if (tlen != GCM_AUTH_TAG_LEN && + tlen != GCM_AUTH_TAG_LEN_8) { + return (err_status_bad_param); + } + + /* allocate memory a cipher of type aes_gcm */ + tmp = sizeof(cipher_t) + sizeof(aes_gcm_ctx_t); + allptr = crypto_alloc(tmp); + if (allptr == NULL) { + return (err_status_alloc_fail); + } + + /* set pointers */ + *c = (cipher_t*)allptr; + (*c)->state = allptr + sizeof(cipher_t); + gcm = (aes_gcm_ctx_t *)(*c)->state; + + /* increment ref_count */ + switch (key_len) { + case AES_128_GCM_KEYSIZE_WSALT: + (*c)->type = &aes_gcm_128_openssl; + (*c)->algorithm = AES_128_GCM; + aes_gcm_128_openssl.ref_count++; + ((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_128_KEYSIZE; + ((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen; + break; + case AES_256_GCM_KEYSIZE_WSALT: + (*c)->type = &aes_gcm_256_openssl; + (*c)->algorithm = AES_256_GCM; + aes_gcm_256_openssl.ref_count++; + ((aes_gcm_ctx_t*)(*c)->state)->key_size = AES_256_KEYSIZE; + ((aes_gcm_ctx_t*)(*c)->state)->tag_len = tlen; + break; + } + + /* set key size */ + (*c)->key_len = key_len; + EVP_CIPHER_CTX_init(&gcm->ctx); + + return (err_status_ok); +} + + +/* + * This function deallocates a GCM session + */ +err_status_t aes_gcm_openssl_dealloc (cipher_t *c) +{ + aes_gcm_ctx_t *ctx; + + ctx = (aes_gcm_ctx_t*)c->state; + if (ctx) { + EVP_CIPHER_CTX_cleanup(&ctx->ctx); + /* decrement ref_count for the appropriate engine */ + switch (ctx->key_size) { + case AES_256_KEYSIZE: + aes_gcm_256_openssl.ref_count--; + break; + case AES_128_KEYSIZE: + aes_gcm_128_openssl.ref_count--; + break; + default: + return (err_status_dealloc_fail); + break; + } + } + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t*)c, sizeof(cipher_t) + sizeof(aes_gcm_ctx_t)); + + /* free memory */ + crypto_free(c); + + 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); +} + + +/* + * aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with + * the offset + */ +err_status_t aes_gcm_openssl_set_iv (aes_gcm_ctx_t *c, void *iv, + int direction) +{ + const EVP_CIPHER *evp; + + if (direction != direction_encrypt && direction != direction_decrypt) { + return (err_status_bad_param); + } + c->dir = direction; + + debug_print(mod_aes_gcm, "setting iv: %s", v128_hex_string(iv)); + + switch (c->key_size) { + case AES_256_KEYSIZE: + evp = EVP_aes_256_gcm(); + break; + case AES_128_KEYSIZE: + evp = EVP_aes_128_gcm(); + break; + default: + return (err_status_bad_param); + break; + } + + if (!EVP_CipherInit_ex(&c->ctx, evp, NULL, (const unsigned char*)&c->key.v8, + NULL, (c->dir == direction_encrypt ? 1 : 0))) { + return (err_status_init_fail); + } + + /* set IV len and the IV value, the followiong 3 calls are required */ + if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) { + return (err_status_init_fail); + } + if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_IV_FIXED, -1, iv)) { + return (err_status_init_fail); + } + if (!EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_IV_GEN, 0, iv)) { + return (err_status_init_fail); + } + + return (err_status_ok); +} + +/* + * This function processes the AAD + * + * Parameters: + * c Crypto context + * aad Additional data to process for AEAD cipher suites + * aad_len length of aad buffer + */ +err_status_t aes_gcm_openssl_set_aad (aes_gcm_ctx_t *c, unsigned char *aad, + unsigned int aad_len) +{ + int rv; + + /* + * Set dummy tag, OpenSSL requires the Tag to be set before + * processing AAD + */ + EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, aad); + + rv = EVP_Cipher(&c->ctx, NULL, aad, aad_len); + if (rv != aad_len) { + return (err_status_algo_fail); + } else { + return (err_status_ok); + } +} + +/* + * This function encrypts a buffer using AES GCM mode + * + * Parameters: + * c Crypto context + * buf data to encrypt + * enc_len length of encrypt buffer + */ +err_status_t aes_gcm_openssl_encrypt (aes_gcm_ctx_t *c, unsigned char *buf, + unsigned int *enc_len) +{ + if (c->dir != direction_encrypt && c->dir != direction_decrypt) { + return (err_status_bad_param); + } + + /* + * Encrypt the data + */ + EVP_Cipher(&c->ctx, buf, buf, *enc_len); + + return (err_status_ok); +} + +/* + * This function calculates and returns the GCM tag for a given context. + * This should be called after encrypting the data. The *len value + * is increased by the tag size. The caller must ensure that *buf has + * enough room to accept the appended tag. + * + * Parameters: + * c Crypto context + * buf data to encrypt + * len length of encrypt buffer + */ +err_status_t aes_gcm_openssl_get_tag (aes_gcm_ctx_t *c, unsigned char *buf, + int *len) +{ + /* + * Calculate the tag + */ + EVP_Cipher(&c->ctx, NULL, NULL, 0); + + /* + * Retreive the tag + */ + EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf); + + /* + * Increase encryption length by desired tag size + */ + *len = c->tag_len; + + return (err_status_ok); +} + + +/* + * This function decrypts a buffer using AES GCM mode + * + * Parameters: + * c Crypto context + * buf data to encrypt + * enc_len length of encrypt buffer + */ +err_status_t aes_gcm_openssl_decrypt (aes_gcm_ctx_t *c, unsigned char *buf, + unsigned int *enc_len) +{ + if (c->dir != direction_encrypt && c->dir != direction_decrypt) { + return (err_status_bad_param); + } + + /* + * Set the tag before decrypting + */ + EVP_CIPHER_CTX_ctrl(&c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, + buf + (*enc_len - c->tag_len)); + EVP_Cipher(&c->ctx, buf, buf, *enc_len - c->tag_len); + + /* + * Check the tag + */ + if (EVP_Cipher(&c->ctx, NULL, NULL, 0)) { + return (err_status_auth_fail); + } + + /* + * Reduce the buffer size by the tag length since the tag + * is not part of the original payload + */ + *enc_len -= c->tag_len; + + return (err_status_ok); +} + + + +/* + * Name of this crypto engine + */ +char aes_gcm_128_openssl_description[] = "AES-128 GCM using openssl"; +char aes_gcm_256_openssl_description[] = "AES-256 GCM using openssl"; + + +/* + * KAT values for AES self-test. These + * values we're derived from independent test code + * using OpenSSL. + */ +uint8_t aes_gcm_test_case_0_key[AES_128_GCM_KEYSIZE_WSALT] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, +}; + +uint8_t aes_gcm_test_case_0_iv[12] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 +}; + +uint8_t aes_gcm_test_case_0_plaintext[60] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 +}; + +uint8_t aes_gcm_test_case_0_aad[20] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 +}; + +uint8_t aes_gcm_test_case_0_ciphertext[76] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, + /* the last 16 bytes are the tag */ + 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, +}; + +cipher_test_case_t aes_gcm_test_case_0a = { + AES_128_GCM_KEYSIZE_WSALT, /* octets in key */ + aes_gcm_test_case_0_key, /* key */ + aes_gcm_test_case_0_iv, /* packet index */ + 60, /* octets in plaintext */ + aes_gcm_test_case_0_plaintext, /* plaintext */ + 68, /* octets in ciphertext */ + aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */ + 20, /* octets in AAD */ + aes_gcm_test_case_0_aad, /* AAD */ + GCM_AUTH_TAG_LEN_8, + NULL /* pointer to next testcase */ +}; + +cipher_test_case_t aes_gcm_test_case_0 = { + AES_128_GCM_KEYSIZE_WSALT, /* octets in key */ + aes_gcm_test_case_0_key, /* key */ + aes_gcm_test_case_0_iv, /* packet index */ + 60, /* octets in plaintext */ + aes_gcm_test_case_0_plaintext, /* plaintext */ + 76, /* octets in ciphertext */ + aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */ + 20, /* octets in AAD */ + aes_gcm_test_case_0_aad, /* AAD */ + GCM_AUTH_TAG_LEN, + &aes_gcm_test_case_0a /* pointer to next testcase */ +}; + +uint8_t aes_gcm_test_case_1_key[AES_256_GCM_KEYSIZE_WSALT] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0xa5, 0x59, 0x09, 0xc5, 0x54, 0x66, 0x93, 0x1c, + 0xaf, 0xf5, 0x26, 0x9a, 0x21, 0xd5, 0x14, 0xb2, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, + +}; + +uint8_t aes_gcm_test_case_1_iv[12] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 +}; + +uint8_t aes_gcm_test_case_1_plaintext[60] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 +}; + +uint8_t aes_gcm_test_case_1_aad[20] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 +}; + +uint8_t aes_gcm_test_case_1_ciphertext[76] = { + 0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46, + 0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a, + 0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86, + 0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a, + 0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9, + 0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80, + 0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10, + 0x09, 0xc9, 0x86, 0xc1, + /* the last 16 bytes are the tag */ + 0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f, + 0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d, +}; + +cipher_test_case_t aes_gcm_test_case_1a = { + AES_256_GCM_KEYSIZE_WSALT, /* octets in key */ + aes_gcm_test_case_1_key, /* key */ + aes_gcm_test_case_1_iv, /* packet index */ + 60, /* octets in plaintext */ + aes_gcm_test_case_1_plaintext, /* plaintext */ + 68, /* octets in ciphertext */ + aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */ + 20, /* octets in AAD */ + aes_gcm_test_case_1_aad, /* AAD */ + GCM_AUTH_TAG_LEN_8, + NULL /* pointer to next testcase */ +}; + +cipher_test_case_t aes_gcm_test_case_1 = { + AES_256_GCM_KEYSIZE_WSALT, /* octets in key */ + aes_gcm_test_case_1_key, /* key */ + aes_gcm_test_case_1_iv, /* packet index */ + 60, /* octets in plaintext */ + aes_gcm_test_case_1_plaintext, /* plaintext */ + 76, /* octets in ciphertext */ + aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */ + 20, /* octets in AAD */ + aes_gcm_test_case_1_aad, /* AAD */ + GCM_AUTH_TAG_LEN, + &aes_gcm_test_case_1a /* pointer to next testcase */ +}; + +/* + * This is the vector function table for this crypto engine. + */ +cipher_type_t aes_gcm_128_openssl = { + (cipher_alloc_func_t) aes_gcm_openssl_alloc, + (cipher_dealloc_func_t) aes_gcm_openssl_dealloc, + (cipher_init_func_t) aes_gcm_openssl_context_init, + (cipher_set_aad_func_t) aes_gcm_openssl_set_aad, + (cipher_encrypt_func_t) aes_gcm_openssl_encrypt, + (cipher_decrypt_func_t) aes_gcm_openssl_decrypt, + (cipher_set_iv_func_t) aes_gcm_openssl_set_iv, + (cipher_get_tag_func_t) aes_gcm_openssl_get_tag, + (char*) aes_gcm_128_openssl_description, + (int) 0, /* instance count */ + (cipher_test_case_t*) &aes_gcm_test_case_0, + (debug_module_t*) &mod_aes_gcm, + (cipher_type_id_t) AES_128_GCM +}; + +/* + * This is the vector function table for this crypto engine. + */ +cipher_type_t aes_gcm_256_openssl = { + (cipher_alloc_func_t) aes_gcm_openssl_alloc, + (cipher_dealloc_func_t) aes_gcm_openssl_dealloc, + (cipher_init_func_t) aes_gcm_openssl_context_init, + (cipher_set_aad_func_t) aes_gcm_openssl_set_aad, + (cipher_encrypt_func_t) aes_gcm_openssl_encrypt, + (cipher_decrypt_func_t) aes_gcm_openssl_decrypt, + (cipher_set_iv_func_t) aes_gcm_openssl_set_iv, + (cipher_get_tag_func_t) aes_gcm_openssl_get_tag, + (char*) aes_gcm_256_openssl_description, + (int) 0, /* instance count */ + (cipher_test_case_t*) &aes_gcm_test_case_1, + (debug_module_t*) &mod_aes_gcm, + (cipher_type_id_t) AES_256_GCM +}; + diff --git a/crypto/cipher/aes_icm_ossl.c b/crypto/cipher/aes_icm_ossl.c index eb58539..1ddd39e 100644 --- a/crypto/cipher/aes_icm_ossl.c +++ b/crypto/cipher/aes_icm_ossl.c @@ -143,6 +143,13 @@ err_status_t aes_icm_openssl_alloc (cipher_t **c, int key_len, int tlen) (*c)->state = allptr + sizeof(cipher_t); icm = (aes_icm_ctx_t*)(*c)->state; + icm->ctx = EVP_CIPHER_CTX_new(); + if (icm->ctx == NULL) { + crypto_free(*c); + *c = NULL; + return err_status_alloc_fail; + } + /* increment ref_count */ switch (key_len) { case AES_128_KEYSIZE_WSALT: @@ -169,7 +176,6 @@ err_status_t aes_icm_openssl_alloc (cipher_t **c, int key_len, int tlen) /* set key size */ (*c)->key_len = key_len; - EVP_CIPHER_CTX_init(&icm->ctx); return err_status_ok; } @@ -191,7 +197,7 @@ err_status_t aes_icm_openssl_dealloc (cipher_t *c) */ ctx = (aes_icm_ctx_t*)c->state; if (ctx != NULL) { - EVP_CIPHER_CTX_cleanup(&ctx->ctx); + EVP_CIPHER_CTX_free(ctx->ctx); /* decrement ref_count for the appropriate engine */ switch (ctx->key_size) { case AES_256_KEYSIZE: @@ -271,7 +277,7 @@ err_status_t aes_icm_openssl_context_init (aes_icm_ctx_t *c, const uint8_t *key, 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); + EVP_CIPHER_CTX_cleanup(c->ctx); return err_status_ok; } @@ -312,7 +318,7 @@ err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, void *iv, int dir) break; } - if (!EVP_EncryptInit_ex(&c->ctx, evp, + if (!EVP_EncryptInit_ex(c->ctx, evp, NULL, c->key.v8, c->counter.v8)) { return err_status_fail; } else { @@ -334,12 +340,12 @@ err_status_t aes_icm_openssl_encrypt (aes_icm_ctx_t *c, unsigned char *buf, unsi debug_print(mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter)); - if (!EVP_EncryptUpdate(&c->ctx, buf, &len, buf, *enc_len)) { + if (!EVP_EncryptUpdate(c->ctx, buf, &len, buf, *enc_len)) { return err_status_cipher_fail; } *enc_len = len; - if (!EVP_EncryptFinal_ex(&c->ctx, buf, &len)) { + if (!EVP_EncryptFinal_ex(c->ctx, buf, &len)) { return err_status_cipher_fail; } *enc_len += len; diff --git a/crypto/cipher/aes_icm_ossl.c.4 b/crypto/cipher/aes_icm_ossl.c.4 new file mode 100644 index 0000000..eb58539 --- /dev/null +++ b/crypto/cipher/aes_icm_ossl.c.4 @@ -0,0 +1,563 @@ +/* + * aes_icm_ossl.c + * + * AES Integer Counter Mode + * + * John A. Foley + * Cisco Systems, Inc. + * + * 2/24/2012: This module was modified to use CiscoSSL for AES counter + * mode. Eddy Lem contributed the code to allow this. + * + * 12/20/2012: Added support for AES-192 and AES-256. + */ + +/* + * + * Copyright (c) 2013, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include +#include "aes_icm_ossl.h" +#include "crypto_types.h" +#include "alloc.h" +#include "crypto_types.h" + + +debug_module_t mod_aes_icm = { + 0, /* debugging is off by default */ + "aes icm ossl" /* printable module name */ +}; +extern cipher_test_case_t aes_icm_test_case_0; +extern cipher_type_t aes_icm; +#ifndef SRTP_NO_AES192 +extern cipher_type_t aes_icm_192; +#endif +extern cipher_type_t aes_icm_256; + +/* + * integer counter mode works as follows: + * + * 16 bits + * <-----> + * +------+------+------+------+------+------+------+------+ + * | nonce | packet index | ctr |---+ + * +------+------+------+------+------+------+------+------+ | + * | + * +------+------+------+------+------+------+------+------+ v + * | salt |000000|->(+) + * +------+------+------+------+------+------+------+------+ | + * | + * +---------+ + * | encrypt | + * +---------+ + * | + * +------+------+------+------+------+------+------+------+ | + * | keystream block |<--+ + * +------+------+------+------+------+------+------+------+ + * + * All fields are big-endian + * + * ctr is the block counter, which increments from zero for + * each packet (16 bits wide) + * + * packet index is distinct for each packet (48 bits wide) + * + * nonce can be distinct across many uses of the same key, or + * can be a fixed value per key, or can be per-packet randomness + * (64 bits) + * + */ + +/* + * This function allocates a new instance of this crypto engine. + * The key_len parameter should be one of 30, 38, or 46 for + * AES-128, AES-192, and AES-256 respectively. Note, this key_len + * value is inflated, as it also accounts for the 112 bit salt + * value. The tlen argument is for the AEAD tag length, which + * isn't used in counter mode. + */ +err_status_t aes_icm_openssl_alloc (cipher_t **c, int key_len, int tlen) +{ + aes_icm_ctx_t *icm; + int tmp; + uint8_t *allptr; + + debug_print(mod_aes_icm, "allocating cipher with key length %d", key_len); + + /* + * Verify the key_len is valid for one of: AES-128/192/256 + */ + if (key_len != AES_128_KEYSIZE_WSALT && +#ifndef SRTP_NO_AES192 + key_len != AES_192_KEYSIZE_WSALT && +#endif + key_len != AES_256_KEYSIZE_WSALT) { + return err_status_bad_param; + } + + /* allocate memory a cipher of type aes_icm */ + tmp = sizeof(cipher_t) + sizeof(aes_icm_ctx_t); + allptr = (uint8_t*)crypto_alloc(tmp); + if (allptr == NULL) { + return err_status_alloc_fail; + } + + /* set pointers */ + *c = (cipher_t*)allptr; + (*c)->state = allptr + sizeof(cipher_t); + icm = (aes_icm_ctx_t*)(*c)->state; + + /* increment ref_count */ + switch (key_len) { + case AES_128_KEYSIZE_WSALT: + (*c)->algorithm = AES_128_ICM; + (*c)->type = &aes_icm; + aes_icm.ref_count++; + ((aes_icm_ctx_t*)(*c)->state)->key_size = AES_128_KEYSIZE; + break; +#ifndef SRTP_NO_AES192 + case AES_192_KEYSIZE_WSALT: + (*c)->algorithm = AES_192_ICM; + (*c)->type = &aes_icm_192; + aes_icm_192.ref_count++; + ((aes_icm_ctx_t*)(*c)->state)->key_size = AES_192_KEYSIZE; + break; +#endif + case AES_256_KEYSIZE_WSALT: + (*c)->algorithm = AES_256_ICM; + (*c)->type = &aes_icm_256; + aes_icm_256.ref_count++; + ((aes_icm_ctx_t*)(*c)->state)->key_size = AES_256_KEYSIZE; + break; + } + + /* set key size */ + (*c)->key_len = key_len; + EVP_CIPHER_CTX_init(&icm->ctx); + + return err_status_ok; +} + + +/* + * This function deallocates an instance of this engine + */ +err_status_t aes_icm_openssl_dealloc (cipher_t *c) +{ + aes_icm_ctx_t *ctx; + + if (c == NULL) { + return err_status_bad_param; + } + + /* + * Free the EVP context + */ + ctx = (aes_icm_ctx_t*)c->state; + if (ctx != NULL) { + EVP_CIPHER_CTX_cleanup(&ctx->ctx); + /* decrement ref_count for the appropriate engine */ + switch (ctx->key_size) { + case AES_256_KEYSIZE: + aes_icm_256.ref_count--; + break; +#ifndef SRTP_NO_AES192 + case AES_192_KEYSIZE: + aes_icm_192.ref_count--; + break; +#endif + case AES_128_KEYSIZE: + aes_icm.ref_count--; + break; + default: + return err_status_dealloc_fail; + break; + } + } + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t*)c, + sizeof(cipher_t) + sizeof(aes_icm_ctx_t)); + + /* free memory */ + crypto_free(c); + + 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 SRTP_NO_AES192 + || 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_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 SRTP_NO_AES192 + 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; + } +} + +/* + * This function encrypts a buffer using AES CTR mode + * + * Parameters: + * c Crypto context + * buf data to encrypt + * enc_len length of encrypt buffer + */ +err_status_t aes_icm_openssl_encrypt (aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) +{ + int len = 0; + + debug_print(mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter)); + + if (!EVP_EncryptUpdate(&c->ctx, buf, &len, buf, *enc_len)) { + return err_status_cipher_fail; + } + *enc_len = len; + + if (!EVP_EncryptFinal_ex(&c->ctx, buf, &len)) { + return err_status_cipher_fail; + } + *enc_len += len; + + return err_status_ok; +} + +uint16_t aes_icm_bytes_encrypted(aes_icm_ctx_t *c) +{ + return htons(c->counter.v16[7]); +} + +/* + * Name of this crypto engine + */ +char aes_icm_openssl_description[] = "AES-128 counter mode using openssl"; +#ifndef SRTP_NO_AES192 +char aes_icm_192_openssl_description[] = "AES-192 counter mode using openssl"; +#endif +char aes_icm_256_openssl_description[] = "AES-256 counter mode using openssl"; + + +/* + * KAT values for AES self-test. These + * values came from the legacy libsrtp code. + */ +uint8_t aes_icm_test_case_0_key[AES_128_KEYSIZE_WSALT] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd +}; + +uint8_t aes_icm_test_case_0_nonce[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8_t aes_icm_test_case_0_plaintext[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t aes_icm_test_case_0_ciphertext[32] = { + 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80, + 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4, + 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7, + 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab +}; + +cipher_test_case_t aes_icm_test_case_0 = { + AES_128_KEYSIZE_WSALT, /* octets in key */ + aes_icm_test_case_0_key, /* key */ + aes_icm_test_case_0_nonce, /* packet index */ + 32, /* octets in plaintext */ + aes_icm_test_case_0_plaintext, /* plaintext */ + 32, /* octets in ciphertext */ + aes_icm_test_case_0_ciphertext, /* ciphertext */ + 0, + NULL, + 0, + NULL /* pointer to next testcase */ +}; + +#ifndef SRTP_NO_AES192 +/* + * KAT values for AES-192-CTR self-test. These + * values came from section 7 of RFC 6188. + */ +uint8_t aes_icm_192_test_case_1_key[AES_192_KEYSIZE_WSALT] = { + 0xea, 0xb2, 0x34, 0x76, 0x4e, 0x51, 0x7b, 0x2d, + 0x3d, 0x16, 0x0d, 0x58, 0x7d, 0x8c, 0x86, 0x21, + 0x97, 0x40, 0xf6, 0x5f, 0x99, 0xb6, 0xbc, 0xf7, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd +}; + +uint8_t aes_icm_192_test_case_1_nonce[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8_t aes_icm_192_test_case_1_plaintext[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t aes_icm_192_test_case_1_ciphertext[32] = { + 0x35, 0x09, 0x6c, 0xba, 0x46, 0x10, 0x02, 0x8d, + 0xc1, 0xb5, 0x75, 0x03, 0x80, 0x4c, 0xe3, 0x7c, + 0x5d, 0xe9, 0x86, 0x29, 0x1d, 0xcc, 0xe1, 0x61, + 0xd5, 0x16, 0x5e, 0xc4, 0x56, 0x8f, 0x5c, 0x9a +}; + +cipher_test_case_t aes_icm_192_test_case_1 = { + AES_192_KEYSIZE_WSALT, /* octets in key */ + aes_icm_192_test_case_1_key, /* key */ + aes_icm_192_test_case_1_nonce, /* packet index */ + 32, /* octets in plaintext */ + aes_icm_192_test_case_1_plaintext, /* plaintext */ + 32, /* octets in ciphertext */ + aes_icm_192_test_case_1_ciphertext, /* ciphertext */ + 0, + NULL, + 0, + NULL /* pointer to next testcase */ +}; +#endif + +/* + * KAT values for AES-256-CTR self-test. These + * values came from section 7 of RFC 6188. + */ +uint8_t aes_icm_256_test_case_2_key[AES_256_KEYSIZE_WSALT] = { + 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70, + 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92, + 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82, + 0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd +}; + +uint8_t aes_icm_256_test_case_2_nonce[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +uint8_t aes_icm_256_test_case_2_plaintext[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +uint8_t aes_icm_256_test_case_2_ciphertext[32] = { + 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25, + 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4, + 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6, + 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac +}; + +cipher_test_case_t aes_icm_256_test_case_2 = { + AES_256_KEYSIZE_WSALT, /* octets in key */ + aes_icm_256_test_case_2_key, /* key */ + aes_icm_256_test_case_2_nonce, /* packet index */ + 32, /* octets in plaintext */ + aes_icm_256_test_case_2_plaintext, /* plaintext */ + 32, /* octets in ciphertext */ + aes_icm_256_test_case_2_ciphertext, /* ciphertext */ + 0, + NULL, + 0, + NULL /* pointer to next testcase */ +}; + +/* + * This is the function table for this crypto engine. + * note: the encrypt function is identical to the decrypt function + */ +cipher_type_t aes_icm = { + (cipher_alloc_func_t) aes_icm_openssl_alloc, + (cipher_dealloc_func_t) aes_icm_openssl_dealloc, + (cipher_init_func_t) aes_icm_openssl_context_init, + (cipher_set_aad_func_t) 0, + (cipher_encrypt_func_t) aes_icm_openssl_encrypt, + (cipher_decrypt_func_t) aes_icm_openssl_encrypt, + (cipher_set_iv_func_t) aes_icm_openssl_set_iv, + (cipher_get_tag_func_t) 0, + (char*) aes_icm_openssl_description, + (int) 0, /* instance count */ + (cipher_test_case_t*) &aes_icm_test_case_0, + (debug_module_t*) &mod_aes_icm, + (cipher_type_id_t) AES_ICM +}; + +#ifndef SRTP_NO_AES192 +/* + * This is the function table for this crypto engine. + * note: the encrypt function is identical to the decrypt function + */ +cipher_type_t aes_icm_192 = { + (cipher_alloc_func_t) aes_icm_openssl_alloc, + (cipher_dealloc_func_t) aes_icm_openssl_dealloc, + (cipher_init_func_t) aes_icm_openssl_context_init, + (cipher_set_aad_func_t) 0, + (cipher_encrypt_func_t) aes_icm_openssl_encrypt, + (cipher_decrypt_func_t) aes_icm_openssl_encrypt, + (cipher_set_iv_func_t) aes_icm_openssl_set_iv, + (cipher_get_tag_func_t) 0, + (char*) aes_icm_192_openssl_description, + (int) 0, /* instance count */ + (cipher_test_case_t*) &aes_icm_192_test_case_1, + (debug_module_t*) &mod_aes_icm, + (cipher_type_id_t) AES_192_ICM +}; +#endif + +/* + * This is the function table for this crypto engine. + * note: the encrypt function is identical to the decrypt function + */ +cipher_type_t aes_icm_256 = { + (cipher_alloc_func_t) aes_icm_openssl_alloc, + (cipher_dealloc_func_t) aes_icm_openssl_dealloc, + (cipher_init_func_t) aes_icm_openssl_context_init, + (cipher_set_aad_func_t) 0, + (cipher_encrypt_func_t) aes_icm_openssl_encrypt, + (cipher_decrypt_func_t) aes_icm_openssl_encrypt, + (cipher_set_iv_func_t) aes_icm_openssl_set_iv, + (cipher_get_tag_func_t) 0, + (char*) aes_icm_256_openssl_description, + (int) 0, /* instance count */ + (cipher_test_case_t*) &aes_icm_256_test_case_2, + (debug_module_t*) &mod_aes_icm, + (cipher_type_id_t) AES_256_ICM +}; + diff --git a/crypto/hash/hmac_ossl.c b/crypto/hash/hmac_ossl.c index f62ce57..3f6f97d 100644 --- a/crypto/hash/hmac_ossl.c +++ b/crypto/hash/hmac_ossl.c @@ -49,8 +49,10 @@ #include "hmac.h" #include "alloc.h" #include +#include -#define HMAC_KEYLEN_MAX 20 +#define HMAC_KEYLEN_MAX 20 +#define SHA1_DIGEST_SIZE 20 /* the debug module for authentiation */ @@ -64,8 +66,6 @@ err_status_t hmac_alloc (auth_t **a, int key_len, int out_len) { extern auth_type_t hmac; - uint8_t *pointer; - hmac_ctx_t *new_hmac_ctx; debug_print(mod_hmac, "allocating auth func with key length %d", key_len); debug_print(mod_hmac, " tag length %d", out_len); @@ -79,25 +79,28 @@ hmac_alloc (auth_t **a, int key_len, int out_len) } /* check output length - should be less than 20 bytes */ - if (out_len > HMAC_KEYLEN_MAX) { + if (out_len > SHA1_DIGEST_SIZE) { return err_status_bad_param; } /* allocate memory for auth and hmac_ctx_t structures */ - pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t)); - if (pointer == NULL) { + *a = crypto_alloc(sizeof(auth_t)); + if (*a == NULL) { + return err_status_alloc_fail; + } + + (*a)->state = HMAC_CTX_new(); + if ((*a)->state == NULL) { + crypto_free(*a); + *a = NULL; return err_status_alloc_fail; } /* set pointers */ - *a = (auth_t*)pointer; (*a)->type = &hmac; - (*a)->state = pointer + sizeof(auth_t); (*a)->out_len = out_len; (*a)->key_len = key_len; (*a)->prefix_len = 0; - new_hmac_ctx = (hmac_ctx_t*)((*a)->state); - memset(new_hmac_ctx, 0, sizeof(hmac_ctx_t)); /* increment global count of all hmac uses */ hmac.ref_count++; @@ -109,19 +112,14 @@ err_status_t hmac_dealloc (auth_t *a) { extern auth_type_t hmac; - hmac_ctx_t *hmac_ctx; + HMAC_CTX *hmac_ctx; - hmac_ctx = (hmac_ctx_t*)a->state; - if (hmac_ctx->ctx_initialized) { - EVP_MD_CTX_cleanup(&hmac_ctx->ctx); - } - if (hmac_ctx->init_ctx_initialized) { - EVP_MD_CTX_cleanup(&hmac_ctx->init_ctx); - } + hmac_ctx = (HMAC_CTX*)a->state; + + HMAC_CTX_free(hmac_ctx); /* zeroize entire state*/ - octet_string_set_to_zero((uint8_t*)a, - sizeof(hmac_ctx_t) + sizeof(auth_t)); + octet_string_set_to_zero((uint8_t*)a, sizeof(auth_t)); /* free memory */ crypto_free(a); @@ -133,109 +131,68 @@ hmac_dealloc (auth_t *a) } err_status_t -hmac_init (hmac_ctx_t *state, const uint8_t *key, int key_len) +hmac_start (hmac_ctx_t *statev) { - int i; - uint8_t ipad[64]; - - /* - * check key length - note that we don't support keys larger - * than 20 bytes yet - */ - if (key_len > HMAC_KEYLEN_MAX) { - return err_status_bad_param; - } - - /* - * set values of ipad and opad by exoring the key into the - * appropriate constant values - */ - for (i = 0; i < key_len; i++) { - ipad[i] = key[i] ^ 0x36; - state->opad[i] = key[i] ^ 0x5c; - } - /* set the rest of ipad, opad to constant values */ - for (; i < sizeof(ipad); i++) { - ipad[i] = 0x36; - ((uint8_t*)state->opad)[i] = 0x5c; - } - - debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, sizeof(ipad))); + HMAC_CTX *state = (HMAC_CTX *)statev; - /* initialize sha1 context */ - sha1_init(&state->init_ctx); - state->init_ctx_initialized = 1; + if (HMAC_Init_ex(state, NULL, 0, NULL, NULL) == 0) + return err_status_auth_fail; - /* hash ipad ^ key */ - sha1_update(&state->init_ctx, ipad, sizeof(ipad)); - return (hmac_start(state)); + return err_status_ok; } err_status_t -hmac_start (hmac_ctx_t *state) +hmac_init (hmac_ctx_t *statev, const uint8_t *key, int key_len) { - if (state->ctx_initialized) { - EVP_MD_CTX_cleanup(&state->ctx); - } - if (!EVP_MD_CTX_copy(&state->ctx, &state->init_ctx)) { + HMAC_CTX *state = (HMAC_CTX *)statev; + + if (HMAC_Init_ex(state, key, key_len, EVP_sha1(), NULL) == 0) return err_status_auth_fail; - } else { - state->ctx_initialized = 1; - return err_status_ok; - } + + return err_status_ok; } err_status_t -hmac_update (hmac_ctx_t *state, const uint8_t *message, int msg_octets) +hmac_update (hmac_ctx_t *statev, const uint8_t *message, int msg_octets) { + HMAC_CTX *state = (HMAC_CTX *)statev; + debug_print(mod_hmac, "input: %s", octet_string_hex_string(message, msg_octets)); - /* hash message into sha1 context */ - sha1_update(&state->ctx, message, msg_octets); + if (HMAC_Update(state, message, msg_octets) == 0) + return err_status_auth_fail; return err_status_ok; } err_status_t -hmac_compute (hmac_ctx_t *state, const void *message, +hmac_compute (hmac_ctx_t *statev, const void *message, int msg_octets, int tag_len, uint8_t *result) { - uint32_t hash_value[5]; - uint32_t H[5]; + HMAC_CTX *state = (HMAC_CTX *)statev; + uint8_t hash_value[SHA1_DIGEST_SIZE]; int i; + unsigned int len; /* check tag length, return error if we can't provide the value expected */ - if (tag_len > HMAC_KEYLEN_MAX) { + if (tag_len > SHA1_DIGEST_SIZE) { return err_status_bad_param; } /* hash message, copy output into H */ - sha1_update(&state->ctx, message, msg_octets); - sha1_final(&state->ctx, H); - - /* - * note that we don't need to debug_print() the input, since the - * function hmac_update() already did that for us - */ - debug_print(mod_hmac, "intermediate state: %s", - octet_string_hex_string((uint8_t*)H, sizeof(H))); - - /* re-initialize hash context */ - sha1_init(&state->ctx); - - /* hash opad ^ key */ - sha1_update(&state->ctx, (uint8_t*)state->opad, sizeof(state->opad)); + if (HMAC_Update(state, message, msg_octets) == 0) + return err_status_auth_fail; - /* hash the result of the inner hash */ - sha1_update(&state->ctx, (uint8_t*)H, sizeof(H)); + if (HMAC_Final(state, hash_value, &len) == 0) + return err_status_auth_fail; - /* the result is returned in the array hash_value[] */ - sha1_final(&state->ctx, hash_value); + if (len < tag_len) + return err_status_auth_fail; /* copy hash_value to *result */ for (i = 0; i < tag_len; i++) { - result[i] = ((uint8_t*)hash_value)[i]; + result[i] = hash_value[i]; } debug_print(mod_hmac, "output: %s", diff --git a/crypto/hash/hmac_ossl.c.4 b/crypto/hash/hmac_ossl.c.4 new file mode 100644 index 0000000..f62ce57 --- /dev/null +++ b/crypto/hash/hmac_ossl.c.4 @@ -0,0 +1,302 @@ +/* + * hmac_ossl.c + * + * Implementation of hmac auth_type_t that leverages OpenSSL + * + * John A. Foley + * Cisco Systems, Inc. + */ +/* + * + * Copyright(c) 2013, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include "hmac.h" +#include "alloc.h" +#include + +#define HMAC_KEYLEN_MAX 20 + +/* the debug module for authentiation */ + +debug_module_t mod_hmac = { + 0, /* debugging is off by default */ + "hmac sha-1 openssl" /* printable name for module */ +}; + + +err_status_t +hmac_alloc (auth_t **a, int key_len, int out_len) +{ + extern auth_type_t hmac; + uint8_t *pointer; + hmac_ctx_t *new_hmac_ctx; + + debug_print(mod_hmac, "allocating auth func with key length %d", key_len); + debug_print(mod_hmac, " tag length %d", out_len); + + /* + * check key length - note that we don't support keys larger + * than 20 bytes yet + */ + if (key_len > HMAC_KEYLEN_MAX) { + return err_status_bad_param; + } + + /* check output length - should be less than 20 bytes */ + if (out_len > HMAC_KEYLEN_MAX) { + return err_status_bad_param; + } + + /* allocate memory for auth and hmac_ctx_t structures */ + pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t)); + if (pointer == NULL) { + return err_status_alloc_fail; + } + + /* set pointers */ + *a = (auth_t*)pointer; + (*a)->type = &hmac; + (*a)->state = pointer + sizeof(auth_t); + (*a)->out_len = out_len; + (*a)->key_len = key_len; + (*a)->prefix_len = 0; + new_hmac_ctx = (hmac_ctx_t*)((*a)->state); + memset(new_hmac_ctx, 0, sizeof(hmac_ctx_t)); + + /* increment global count of all hmac uses */ + hmac.ref_count++; + + return err_status_ok; +} + +err_status_t +hmac_dealloc (auth_t *a) +{ + extern auth_type_t hmac; + hmac_ctx_t *hmac_ctx; + + hmac_ctx = (hmac_ctx_t*)a->state; + if (hmac_ctx->ctx_initialized) { + EVP_MD_CTX_cleanup(&hmac_ctx->ctx); + } + if (hmac_ctx->init_ctx_initialized) { + EVP_MD_CTX_cleanup(&hmac_ctx->init_ctx); + } + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t*)a, + sizeof(hmac_ctx_t) + sizeof(auth_t)); + + /* free memory */ + crypto_free(a); + + /* decrement global count of all hmac uses */ + hmac.ref_count--; + + return err_status_ok; +} + +err_status_t +hmac_init (hmac_ctx_t *state, const uint8_t *key, int key_len) +{ + int i; + uint8_t ipad[64]; + + /* + * check key length - note that we don't support keys larger + * than 20 bytes yet + */ + if (key_len > HMAC_KEYLEN_MAX) { + return err_status_bad_param; + } + + /* + * set values of ipad and opad by exoring the key into the + * appropriate constant values + */ + for (i = 0; i < key_len; i++) { + ipad[i] = key[i] ^ 0x36; + state->opad[i] = key[i] ^ 0x5c; + } + /* set the rest of ipad, opad to constant values */ + for (; i < sizeof(ipad); i++) { + ipad[i] = 0x36; + ((uint8_t*)state->opad)[i] = 0x5c; + } + + debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, sizeof(ipad))); + + /* initialize sha1 context */ + sha1_init(&state->init_ctx); + state->init_ctx_initialized = 1; + + /* hash ipad ^ key */ + sha1_update(&state->init_ctx, ipad, sizeof(ipad)); + return (hmac_start(state)); +} + +err_status_t +hmac_start (hmac_ctx_t *state) +{ + if (state->ctx_initialized) { + EVP_MD_CTX_cleanup(&state->ctx); + } + if (!EVP_MD_CTX_copy(&state->ctx, &state->init_ctx)) { + return err_status_auth_fail; + } else { + state->ctx_initialized = 1; + return err_status_ok; + } +} + +err_status_t +hmac_update (hmac_ctx_t *state, const uint8_t *message, int msg_octets) +{ + debug_print(mod_hmac, "input: %s", + octet_string_hex_string(message, msg_octets)); + + /* hash message into sha1 context */ + sha1_update(&state->ctx, message, msg_octets); + + return err_status_ok; +} + +err_status_t +hmac_compute (hmac_ctx_t *state, const void *message, + int msg_octets, int tag_len, uint8_t *result) +{ + uint32_t hash_value[5]; + uint32_t H[5]; + int i; + + /* check tag length, return error if we can't provide the value expected */ + if (tag_len > HMAC_KEYLEN_MAX) { + return err_status_bad_param; + } + + /* hash message, copy output into H */ + sha1_update(&state->ctx, message, msg_octets); + sha1_final(&state->ctx, H); + + /* + * note that we don't need to debug_print() the input, since the + * function hmac_update() already did that for us + */ + debug_print(mod_hmac, "intermediate state: %s", + octet_string_hex_string((uint8_t*)H, sizeof(H))); + + /* re-initialize hash context */ + sha1_init(&state->ctx); + + /* hash opad ^ key */ + sha1_update(&state->ctx, (uint8_t*)state->opad, sizeof(state->opad)); + + /* hash the result of the inner hash */ + sha1_update(&state->ctx, (uint8_t*)H, sizeof(H)); + + /* the result is returned in the array hash_value[] */ + sha1_final(&state->ctx, hash_value); + + /* copy hash_value to *result */ + for (i = 0; i < tag_len; i++) { + result[i] = ((uint8_t*)hash_value)[i]; + } + + debug_print(mod_hmac, "output: %s", + octet_string_hex_string((uint8_t*)hash_value, tag_len)); + + return err_status_ok; +} + + +/* begin test case 0 */ + +uint8_t + hmac_test_case_0_key[HMAC_KEYLEN_MAX] = { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b +}; + +uint8_t + hmac_test_case_0_data[8] = { + 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */ +}; + +uint8_t + hmac_test_case_0_tag[HMAC_KEYLEN_MAX] = { + 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, + 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, + 0xf1, 0x46, 0xbe, 0x00 +}; + +auth_test_case_t + hmac_test_case_0 = { + sizeof(hmac_test_case_0_key), /* octets in key */ + hmac_test_case_0_key, /* key */ + sizeof(hmac_test_case_0_data), /* octets in data */ + hmac_test_case_0_data, /* data */ + sizeof(hmac_test_case_0_tag), /* octets in tag */ + hmac_test_case_0_tag, /* tag */ + NULL /* pointer to next testcase */ +}; + +/* end test case 0 */ + +char hmac_description[] = "hmac sha-1 authentication function"; + +/* + * auth_type_t hmac is the hmac metaobject + */ + +auth_type_t + hmac = { + (auth_alloc_func) hmac_alloc, + (auth_dealloc_func) hmac_dealloc, + (auth_init_func) hmac_init, + (auth_compute_func) hmac_compute, + (auth_update_func) hmac_update, + (auth_start_func) hmac_start, + (char*) hmac_description, + (int) 0, /* instance count */ + (auth_test_case_t*) &hmac_test_case_0, + (debug_module_t*) &mod_hmac, + (auth_type_id_t) HMAC_SHA1 +}; + diff --git a/crypto/include/aes_gcm_ossl.h b/crypto/include/aes_gcm_ossl.h index 8e7711d..4f49b51 100644 --- a/crypto/include/aes_gcm_ossl.h +++ b/crypto/include/aes_gcm_ossl.h @@ -55,7 +55,7 @@ typedef struct { v256_t key; int key_size; int tag_len; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX* ctx; cipher_direction_t dir; } aes_gcm_ctx_t; diff --git a/crypto/include/aes_gcm_ossl.h.4 b/crypto/include/aes_gcm_ossl.h.4 new file mode 100644 index 0000000..8e7711d --- /dev/null +++ b/crypto/include/aes_gcm_ossl.h.4 @@ -0,0 +1,63 @@ +/* + * aes_gcm_ossl.h + * + * Header for AES Galois Counter Mode. + * + * John A. Foley + * Cisco Systems, Inc. + * + */ +/* + * + * Copyright (c) 2013, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef AES_GCM_OSSL_H +#define AES_GCM_OSSL_H + +#include "cipher.h" +#include "srtp.h" +#include +#include + +typedef struct { + v256_t key; + int key_size; + int tag_len; + EVP_CIPHER_CTX ctx; + cipher_direction_t dir; +} aes_gcm_ctx_t; + +#endif /* AES_GCM_OSSL_H */ + diff --git a/crypto/include/aes_icm_ossl.h b/crypto/include/aes_icm_ossl.h index b4ec40a..af23320 100644 --- a/crypto/include/aes_icm_ossl.h +++ b/crypto/include/aes_icm_ossl.h @@ -72,7 +72,7 @@ typedef struct { v128_t offset; /* initial offset value */ v256_t key; int key_size; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX* ctx; } aes_icm_ctx_t; err_status_t aes_icm_openssl_set_iv(aes_icm_ctx_t *c, void *iv, int dir); diff --git a/crypto/include/aes_icm_ossl.h.4 b/crypto/include/aes_icm_ossl.h.4 new file mode 100644 index 0000000..b4ec40a --- /dev/null +++ b/crypto/include/aes_icm_ossl.h.4 @@ -0,0 +1,85 @@ +/* + * aes_icm.h + * + * Header for AES Integer Counter Mode. + * + * David A. McGrew + * Cisco Systems, Inc. + * + */ +/* + * + * Copyright (c) 2001-2005,2012, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef AES_ICM_H +#define AES_ICM_H + +#include "cipher.h" +#include +#include + +#ifdef OPENSSL_IS_BORINGSSL +// BoringSSL doesn't support AES-192, cipher will be disabled +#define SRTP_NO_AES192 +#endif + +#define SALT_SIZE 14 +#define AES_128_KEYSIZE AES_BLOCK_SIZE +#ifndef SRTP_NO_AES192 +#define AES_192_KEYSIZE AES_BLOCK_SIZE + AES_BLOCK_SIZE / 2 +#endif +#define AES_256_KEYSIZE AES_BLOCK_SIZE * 2 +#define AES_128_KEYSIZE_WSALT AES_128_KEYSIZE + SALT_SIZE +#ifndef SRTP_NO_AES192 +#define AES_192_KEYSIZE_WSALT AES_192_KEYSIZE + SALT_SIZE +#endif +#define AES_256_KEYSIZE_WSALT AES_256_KEYSIZE + SALT_SIZE + +typedef struct { + v128_t counter; /* holds the counter value */ + v128_t offset; /* initial offset value */ + v256_t key; + int key_size; + EVP_CIPHER_CTX ctx; +} aes_icm_ctx_t; + +err_status_t aes_icm_openssl_set_iv(aes_icm_ctx_t *c, void *iv, int dir); +err_status_t aes_icm_openssl_context_init(aes_icm_ctx_t *c, const uint8_t *key, int len); +err_status_t aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output); +uint16_t aes_icm_bytes_encrypted(aes_icm_ctx_t *c); + + +#endif /* AES_ICM_H */ + diff --git a/crypto/include/sha1.h b/crypto/include/sha1.h index 2ce53e8..fb5bd95 100644 --- a/crypto/include/sha1.h +++ b/crypto/include/sha1.h @@ -56,8 +56,6 @@ #include #include -typedef EVP_MD_CTX sha1_ctx_t; - /* * sha1_init(&ctx) initializes the SHA1 context ctx * @@ -72,23 +70,27 @@ typedef EVP_MD_CTX sha1_ctx_t; * */ +typedef EVP_MD_CTX* sha1_ctx_t; + static inline void sha1_init (sha1_ctx_t *ctx) { - EVP_MD_CTX_init(ctx); - EVP_DigestInit(ctx, EVP_sha1()); + *ctx = EVP_MD_CTX_new(); + EVP_DigestInit(*ctx, EVP_sha1()); } static inline void sha1_update (sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg) { - EVP_DigestUpdate(ctx, M, octets_in_msg); + EVP_DigestUpdate(*ctx, M, octets_in_msg); } static inline void sha1_final (sha1_ctx_t *ctx, uint32_t *output) { unsigned int len = 0; - EVP_DigestFinal(ctx, (unsigned char*)output, &len); + EVP_DigestFinal(*ctx, (unsigned char*)output, &len); + EVP_MD_CTX_free(*ctx); } + #else #include "datatypes.h" diff --git a/crypto/include/sha1.h.4 b/crypto/include/sha1.h.4 new file mode 100644 index 0000000..2ce53e8 --- /dev/null +++ b/crypto/include/sha1.h.4 @@ -0,0 +1,152 @@ +/* + * sha1.h + * + * interface to the Secure Hash Algorithm v.1 (SHA-1), specified in + * FIPS 180-1 + * + * David A. McGrew + * Cisco Systems, Inc. + */ + +/* + * + * Copyright (c) 2001-2006, Cisco Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * Neither the name of the Cisco Systems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef SHA1_H +#define SHA1_H + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include "err.h" +#ifdef OPENSSL +#include +#include + +typedef EVP_MD_CTX sha1_ctx_t; + +/* + * sha1_init(&ctx) initializes the SHA1 context ctx + * + * sha1_update(&ctx, msg, len) hashes the len octets starting at msg + * into the SHA1 context + * + * sha1_final(&ctx, output) performs the final processing of the SHA1 + * context and writes the result to the 20 octets at output + * + * Return values are ignored on the EVP functions since all three + * of these functions return void. + * + */ + +static inline void sha1_init (sha1_ctx_t *ctx) +{ + EVP_MD_CTX_init(ctx); + EVP_DigestInit(ctx, EVP_sha1()); +} + +static inline void sha1_update (sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg) +{ + EVP_DigestUpdate(ctx, M, octets_in_msg); +} + +static inline void sha1_final (sha1_ctx_t *ctx, uint32_t *output) +{ + unsigned int len = 0; + + EVP_DigestFinal(ctx, (unsigned char*)output, &len); +} +#else +#include "datatypes.h" + +typedef struct { + uint32_t H[5]; /* state vector */ + uint32_t M[16]; /* message buffer */ + int octets_in_buffer; /* octets of message in buffer */ + uint32_t num_bits_in_msg; /* total number of bits in message */ +} sha1_ctx_t; + +/* + * sha1(&ctx, msg, len, output) hashes the len octets starting at msg + * into the SHA1 context, then writes the result to the 20 octets at + * output + * + */ + +void +crypto_sha1(const uint8_t *message, int octets_in_msg, uint32_t output[5]); + +/* + * sha1_init(&ctx) initializes the SHA1 context ctx + * + * sha1_update(&ctx, msg, len) hashes the len octets starting at msg + * into the SHA1 context + * + * sha1_final(&ctx, output) performs the final processing of the SHA1 + * context and writes the result to the 20 octets at output + * + */ + +void +crypto_sha1_init(sha1_ctx_t *ctx); + +void +crypto_sha1_update(sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg); + +void +crypto_sha1_final(sha1_ctx_t *ctx, uint32_t output[5]); + +/* + * The sha1_core function is INTERNAL to SHA-1, but it is declared + * here because it is also used by the cipher SEAL 3.0 in its key + * setup algorithm. + */ + +/* + * sha1_core(M, H) computes the core sha1 compression function, where M is + * the next part of the message and H is the intermediate state {H0, + * H1, ...} + * + * this function does not do any of the padding required in the + * complete sha1 function + */ + +void +crypto_sha1_core(const uint32_t M[16], uint32_t hash_value[5]); + +#endif /* else OPENSSL */ + +#endif /* SHA1_H */