diff options
author | Jakub Zelenka <jakub.openssl@gmail.com> | 2020-09-06 19:11:34 +0100 |
---|---|---|
committer | Tomas Mraz <tmraz@fedoraproject.org> | 2020-09-08 15:43:11 +0200 |
commit | 924663c36d47066d5307937da77fed7e872730c7 (patch) | |
tree | a60cfe385cc29402bdaceaaa5a8b069ca6a6a50a /crypto/evp | |
parent | d96486dc809b5d134055785bfa6d707195d95534 (diff) |
Add CMS AuthEnvelopedData with AES-GCM support
Add the AuthEnvelopedData as defined in RFC 5083 with AES-GCM
parameter as defined in RFC 5084.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/8024)
Diffstat (limited to 'crypto/evp')
-rw-r--r-- | crypto/evp/evp_lib.c | 107 | ||||
-rw-r--r-- | crypto/evp/evp_local.h | 5 |
2 files changed, 84 insertions, 28 deletions
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 676461a51b..81151e4f01 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -22,12 +22,60 @@ #include <openssl/dh.h> #include <openssl/ec.h> #include "crypto/evp.h" +#include "crypto/asn1.h" #include "internal/provider.h" #include "evp_local.h" #if !defined(FIPS_MODULE) int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) { + return evp_cipher_param_to_asn1_ex(c, type, NULL); +} + +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + return evp_cipher_asn1_to_param_ex(c, type, NULL); +} + +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *ctx, ASN1_TYPE *type) +{ + int i = 0; + unsigned int l; + + if (type != NULL) { + unsigned char iv[EVP_MAX_IV_LENGTH]; + + l = EVP_CIPHER_CTX_iv_length(ctx); + if (!ossl_assert(l <= sizeof(iv))) + return -1; + i = ASN1_TYPE_get_octetstring(type, iv, l); + if (i != (int)l) + return -1; + + if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1)) + return -1; + } + return i; +} + +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + unsigned int j; + unsigned char *oiv = NULL; + + if (type != NULL) { + oiv = (unsigned char *)EVP_CIPHER_CTX_original_iv(c); + j = EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(j <= sizeof(c->iv)); + i = ASN1_TYPE_set_octetstring(type, oiv, j); + } + return i; +} + +int evp_cipher_param_to_asn1_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) +{ int ret = -1; /* Assume the worst */ const EVP_CIPHER *cipher = c->cipher; @@ -58,6 +106,9 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) break; case EVP_CIPH_GCM_MODE: + ret = evp_cipher_set_asn1_aead_params(c, type, asn1_params); + break; + case EVP_CIPH_CCM_MODE: case EVP_CIPH_XTS_MODE: case EVP_CIPH_OCB_MODE: @@ -104,15 +155,16 @@ int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) err: if (ret == -2) - EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, ASN1_R_UNSUPPORTED_CIPHER); + EVPerr(0, EVP_R_UNSUPPORTED_CIPHER); else if (ret <= 0) - EVPerr(EVP_F_EVP_CIPHER_PARAM_TO_ASN1, EVP_R_CIPHER_PARAMETER_ERROR); + EVPerr(0, EVP_R_CIPHER_PARAMETER_ERROR); if (ret < -1) ret = -1; return ret; } -int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { int ret = -1; /* Assume the worst */ const EVP_CIPHER *cipher = c->cipher; @@ -142,6 +194,9 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) break; case EVP_CIPH_GCM_MODE: + ret = evp_cipher_get_asn1_aead_params(c, type, asn1_params); + break; + case EVP_CIPH_CCM_MODE: case EVP_CIPH_XTS_MODE: case EVP_CIPH_OCB_MODE: @@ -170,47 +225,43 @@ int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) } if (ret == -2) - EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, EVP_R_UNSUPPORTED_CIPHER); + EVPerr(0, EVP_R_UNSUPPORTED_CIPHER); else if (ret <= 0) - EVPerr(EVP_F_EVP_CIPHER_ASN1_TO_PARAM, EVP_R_CIPHER_PARAMETER_ERROR); + EVPerr(0, EVP_R_CIPHER_PARAMETER_ERROR); if (ret < -1) ret = -1; return ret; } -int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *ctx, ASN1_TYPE *type) +int evp_cipher_get_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { int i = 0; - unsigned int l; + long tl; + unsigned char iv[EVP_MAX_IV_LENGTH]; - if (type != NULL) { - unsigned char iv[EVP_MAX_IV_LENGTH]; + if (type == NULL || asn1_params == NULL) + return 0; - l = EVP_CIPHER_CTX_iv_length(ctx); - if (!ossl_assert(l <= sizeof(iv))) - return -1; - i = ASN1_TYPE_get_octetstring(type, iv, l); - if (i != (int)l) - return -1; + i = asn1_type_get_octetstring_int(type, &tl, NULL, EVP_MAX_IV_LENGTH); + if (i <= 0) + return -1; + asn1_type_get_octetstring_int(type, &tl, iv, i); + + memcpy(asn1_params->iv, iv, i); + asn1_params->iv_len = i; - if (!EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, -1)) - return -1; - } return i; } -int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +int evp_cipher_set_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params) { - int i = 0; - unsigned int j; - unsigned char oiv[EVP_MAX_IV_LENGTH]; + if (type == NULL || asn1_params == NULL) + return 0; - if (type != NULL && EVP_CIPHER_CTX_get_iv(c, oiv, sizeof(oiv))) { - j = EVP_CIPHER_CTX_iv_length(c); - OPENSSL_assert(j <= sizeof(c->iv)); - i = ASN1_TYPE_set_octetstring(type, oiv, j); - } - return i; + return asn1_type_set_octetstring_int(type, asn1_params->tag_len, + asn1_params->iv, asn1_params->iv_len); } #endif /* !defined(FIPS_MODULE) */ diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index 1e1d689070..e7f7643d83 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -240,6 +240,11 @@ EVP_KEYMGMT *evp_keymgmt_fetch_by_number(OPENSSL_CTX *ctx, int name_id, EVP_MD *evp_md_new(void); EVP_CIPHER *evp_cipher_new(void); +int evp_cipher_get_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params); +int evp_cipher_set_asn1_aead_params(EVP_CIPHER_CTX *c, ASN1_TYPE *type, + evp_cipher_aead_asn1_params *asn1_params); + /* Helper functions to avoid duplicating code */ /* |