Backport of https://github.com/cisco/libsrtp/commit/0b45423678ddc46d702f3a51614f20bfbd112ddd --- a/crypto/cipher/aes_gcm_ossl.c 2018-06-11 07:46:09 UTC +++ b/crypto/cipher/aes_gcm_ossl.c @@ -117,6 +117,14 @@ err_status_t aes_gcm_openssl_alloc (cipher_t **c, int } memset(gcm, 0x0, sizeof(aes_gcm_ctx_t)); + gcm->ctx = EVP_CIPHER_CTX_new(); + if (gcm->ctx == NULL) { + crypto_free(gcm); + crypto_free(*c); + *c = NULL; + return err_status_alloc_fail; + } + /* set pointers */ (*c)->state = gcm; @@ -140,7 +148,6 @@ err_status_t aes_gcm_openssl_alloc (cipher_t **c, int /* set key size */ (*c)->key_len = key_len; - EVP_CIPHER_CTX_init(&gcm->ctx); return (err_status_ok); } @@ -155,7 +162,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: @@ -205,7 +212,7 @@ err_status_t aes_gcm_openssl_context_init (aes_gcm_ctx break; } - if (!EVP_CipherInit_ex(&c->ctx, evp, NULL, key, NULL, 0)) { + if (!EVP_CipherInit_ex(c->ctx, evp, NULL, key, NULL, 0)) { return (err_status_init_fail); } @@ -227,19 +234,19 @@ err_status_t aes_gcm_openssl_set_iv (aes_gcm_ctx_t *c, debug_print(mod_aes_gcm, "setting iv: %s", v128_hex_string(iv)); - if (!EVP_CipherInit_ex(&c->ctx, NULL, NULL, NULL, + if (!EVP_CipherInit_ex(c->ctx, NULL, NULL, NULL, 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); } @@ -263,9 +270,9 @@ err_status_t aes_gcm_openssl_set_aad (aes_gcm_ctx_t *c * 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 { @@ -291,7 +298,7 @@ err_status_t aes_gcm_openssl_encrypt (aes_gcm_ctx_t *c /* * Encrypt the data */ - EVP_Cipher(&c->ctx, buf, buf, *enc_len); + EVP_Cipher(c->ctx, buf, buf, *enc_len); return (err_status_ok); } @@ -313,12 +320,12 @@ err_status_t aes_gcm_openssl_get_tag (aes_gcm_ctx_t *c /* * 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 @@ -347,14 +354,14 @@ err_status_t aes_gcm_openssl_decrypt (aes_gcm_ctx_t *c /* * 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); } --- a/crypto/cipher/aes_icm_ossl.c 2018-06-11 07:46:00 UTC +++ b/crypto/cipher/aes_icm_ossl.c @@ -144,6 +144,14 @@ err_status_t aes_icm_openssl_alloc (cipher_t **c, int } memset(icm, 0x0, sizeof(aes_icm_ctx_t)); + icm->ctx = EVP_CIPHER_CTX_new(); + if (icm->ctx == NULL) { + crypto_free(icm); + crypto_free(*c); + *c = NULL; + return err_status_alloc_fail; + } + /* set pointers */ (*c)->state = icm; @@ -173,7 +181,6 @@ err_status_t aes_icm_openssl_alloc (cipher_t **c, int /* set key size */ (*c)->key_len = key_len; - EVP_CIPHER_CTX_init(&icm->ctx); return err_status_ok; } @@ -195,7 +202,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: @@ -257,8 +264,6 @@ err_status_t aes_icm_openssl_context_init (aes_icm_ctx debug_print(mod_aes_icm, "key: %s", octet_string_hex_string(key, c->key_size)); debug_print(mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); - EVP_CIPHER_CTX_init(&c->ctx); - switch (c->key_size) { case AES_256_KEYSIZE: evp = EVP_aes_256_ctr(); @@ -276,7 +281,7 @@ err_status_t aes_icm_openssl_context_init (aes_icm_ctx break; } - if (!EVP_EncryptInit_ex(&c->ctx, evp, + if (!EVP_EncryptInit_ex(c->ctx, evp, NULL, key, NULL)) { return err_status_fail; } else { @@ -304,7 +309,7 @@ err_status_t aes_icm_openssl_set_iv (aes_icm_ctx_t *c, debug_print(mod_aes_icm, "set_counter: %s", v128_hex_string(&c->counter)); - if (!EVP_EncryptInit_ex(&c->ctx, NULL, + if (!EVP_EncryptInit_ex(c->ctx, NULL, NULL, NULL, c->counter.v8)) { return err_status_fail; } else { @@ -326,12 +331,12 @@ err_status_t aes_icm_openssl_encrypt (aes_icm_ctx_t *c 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; --- a/crypto/hash/hmac_ossl.c 2018-06-11 07:45:39 UTC +++ b/crypto/hash/hmac_ossl.c @@ -65,8 +65,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 *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); @@ -76,21 +74,43 @@ hmac_alloc (auth_t **a, int key_len, int out_len) return err_status_bad_param; } - /* allocate memory for auth and HMAC_CTX structures */ - pointer = (uint8_t*)crypto_alloc(sizeof(HMAC_CTX) + sizeof(auth_t)); - if (pointer == NULL) { +/* OpenSSL 1.1.0 made HMAC_CTX an opaque structure, which must be allocated + using HMAC_CTX_new. But this function doesn't exist in OpenSSL 1.0.x. */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) + { + /* allocate memory for auth and HMAC_CTX structures */ + uint8_t* pointer; + HMAC_CTX *new_hmac_ctx; + pointer = (uint8_t*)crypto_alloc(sizeof(HMAC_CTX) + sizeof(auth_t)); + if (pointer == NULL) { + return err_status_alloc_fail; + } + *a = (auth_t*)pointer; + (*a)->state = pointer + sizeof(auth_t); + new_hmac_ctx = (HMAC_CTX*)((*a)->state); + + HMAC_CTX_init(new_hmac_ctx); + } + +#else + *a = (auth_t*)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; + } +#endif + /* 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*)((*a)->state); - HMAC_CTX_init(new_hmac_ctx); /* increment global count of all hmac uses */ hmac.ref_count++; @@ -106,11 +126,19 @@ hmac_dealloc (auth_t *a) hmac_ctx = (HMAC_CTX*)a->state; +#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) HMAC_CTX_cleanup(hmac_ctx); /* zeroize entire state*/ octet_string_set_to_zero((uint8_t*)a, sizeof(HMAC_CTX) + sizeof(auth_t)); + +#else + HMAC_CTX_free(hmac_ctx); + + /* zeroize entire state*/ + octet_string_set_to_zero((uint8_t*)a, sizeof(auth_t)); +#endif /* free memory */ crypto_free(a); --- a/crypto/include/aes_gcm_ossl.h 2018-06-11 07:46:09 UTC +++ b/crypto/include/aes_gcm_ossl.h @@ -54,7 +54,7 @@ typedef struct { int key_size; int tag_len; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX* ctx; cipher_direction_t dir; } aes_gcm_ctx_t; --- a/crypto/include/aes_icm_ossl.h 2018-06-11 07:46:00 UTC +++ b/crypto/include/aes_icm_ossl.h @@ -71,7 +71,7 @@ typedef struct { v128_t counter; /* holds the counter value */ v128_t offset; /* initial offset value */ 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); --- a/crypto/include/sha1.h 2017-08-01 11:57:38 UTC +++ 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,6 +70,12 @@ typedef EVP_MD_CTX sha1_ctx_t; * */ +/* OpenSSL 1.1.0 made EVP_MD_CTX an opaque structure, which must be allocated + using EVP_MD_CTX_new. But this function doesn't exist in OpenSSL 1.0.x. */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL) + +typedef EVP_MD_CTX sha1_ctx_t; + static inline void sha1_init (sha1_ctx_t *ctx) { EVP_MD_CTX_init(ctx); @@ -88,7 +92,33 @@ static inline void sha1_final (sha1_ctx_t *ctx, uint32 unsigned int len = 0; EVP_DigestFinal(ctx, (unsigned char*)output, &len); + EVP_MD_CTX_cleanup(ctx); } + +#else + +typedef EVP_MD_CTX* sha1_ctx_t; + +static inline void sha1_init (sha1_ctx_t *ctx) +{ + *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); +} + +static inline void sha1_final (sha1_ctx_t *ctx, uint32_t *output) +{ + unsigned int len = 0; + + EVP_DigestFinal(*ctx, (unsigned char*)output, &len); + EVP_MD_CTX_free(*ctx); +} +#endif + #else #include "datatypes.h"