Loading CHANGES +11 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,17 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) Add GCM support to TLS library. Some custom code is needed to split the IV between the fixed (from PRF) and explicit (from TLS record) portions. This adds all GCM ciphersuites supported by RFC5288 and RFC5289. Generalise some AES* cipherstrings to inlclude GCM and add a special AESGCM string for GCM only. [Steve Henson] *) Expand range of ctrls for AES GCM. Permit setting invocation field on decrypt and retrieval of invocation field only on encrypt. [Steve Henson] *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support. As required by RFC5289 these ciphersuites cannot be used if for versions of TLS earlier than 1.2. Loading crypto/evp/c_allc.c +3 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_aes_128_cfb8()); EVP_add_cipher(EVP_aes_128_ofb()); EVP_add_cipher(EVP_aes_128_ctr()); EVP_add_cipher(EVP_aes_128_gcm()); EVP_add_cipher_alias(SN_aes_128_cbc,"AES128"); EVP_add_cipher_alias(SN_aes_128_cbc,"aes128"); EVP_add_cipher(EVP_aes_192_ecb()); Loading @@ -176,6 +177,7 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_aes_192_cfb8()); EVP_add_cipher(EVP_aes_192_ofb()); EVP_add_cipher(EVP_aes_192_ctr()); EVP_add_cipher(EVP_aes_192_gcm()); EVP_add_cipher_alias(SN_aes_192_cbc,"AES192"); EVP_add_cipher_alias(SN_aes_192_cbc,"aes192"); EVP_add_cipher(EVP_aes_256_ecb()); Loading @@ -185,6 +187,7 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_aes_256_cfb8()); EVP_add_cipher(EVP_aes_256_ofb()); EVP_add_cipher(EVP_aes_256_ctr()); EVP_add_cipher(EVP_aes_256_gcm()); EVP_add_cipher_alias(SN_aes_256_cbc,"AES256"); EVP_add_cipher_alias(SN_aes_256_cbc,"aes256"); #endif Loading crypto/evp/e_aes.c +108 −6 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ typedef struct int ivlen; /* IV length */ int taglen; int iv_gen; /* It is OK to generate IVs */ int tls_aad_len; /* TLS AAD length */ } EVP_AES_GCM_CTX; typedef struct Loading Loading @@ -748,6 +749,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; gctx->tls_aad_len = -1; return 1; case EVP_CTRL_GCM_SET_IVLEN: Loading Loading @@ -798,7 +800,8 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; if (arg) memcpy(gctx->iv, ptr, arg); if (RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) if (c->encrypt && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) return 0; gctx->iv_gen = 1; return 1; Loading @@ -807,7 +810,9 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (gctx->iv_gen == 0 || gctx->key_set == 0) return 0; CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); memcpy(ptr, gctx->iv, gctx->ivlen); if (arg <= 0 || arg > gctx->ivlen) arg = gctx->ivlen; memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); /* Invocation field will be at least 8 bytes in size and * so no need to check wrap around or increment more than * last 8 bytes. Loading @@ -816,6 +821,33 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) gctx->iv_set = 1; return 1; case EVP_CTRL_GCM_SET_IV_INV: if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) return 0; memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); gctx->iv_set = 1; return 1; case EVP_CTRL_AEAD_TLS1_AAD: /* Save the AAD for later use */ if (arg != 13) return 0; memcpy(c->buf, ptr, arg); gctx->tls_aad_len = arg; { unsigned int len=c->buf[arg-2]<<8|c->buf[arg-1]; /* Correct length for explicit IV */ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!c->encrypt) len -= EVP_GCM_TLS_TAG_LEN; c->buf[arg-2] = len>>8; c->buf[arg-1] = len & 0xff; } /* Extra padding: tag appended to record */ return EVP_GCM_TLS_TAG_LEN; default: return -1; Loading Loading @@ -857,12 +889,79 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 1; } /* Handle TLS GCM packet format. This consists of the last portion of the IV * followed by the payload and finally the tag. On encrypt generate IV, * encrypt payload and write the tag. On verify retrieve IV, decrypt payload * and verify tag. */ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_GCM_CTX *gctx = ctx->cipher_data; int rv = -1; /* Encrypt/decrypt must be performed in place */ if (out != in) return -1; /* Set IV from start of buffer or generate IV and write to start * of buffer. */ if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) goto err; /* Use saved AAD */ if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) goto err; /* Fix buffer and length to point to payload */ in += EVP_GCM_TLS_EXPLICIT_IV_LEN; out += EVP_GCM_TLS_EXPLICIT_IV_LEN; len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; if (ctx->encrypt) { /* Encrypt payload */ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) goto err; out += len; /* Finally write tag */ CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; } else { /* Decrypt */ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) goto err; /* Retrieve tag */ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); /* If tag mismatch wipe buffer */ if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { OPENSSL_cleanse(out, len); goto err; } rv = len; } err: gctx->iv_set = 0; gctx->tls_aad_len = -1; return rv; } static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_GCM_CTX *gctx = ctx->cipher_data; /* If not set up, return error */ if (!gctx->iv_set && !gctx->key_set) if (!gctx->key_set) return -1; if (gctx->tls_aad_len >= 0) return aes_gcm_tls_cipher(ctx, out, in, len); if (!gctx->iv_set) return -1; if (!ctx->encrypt && gctx->taglen < 0) return -1; Loading Loading @@ -908,9 +1007,12 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT) BLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM, EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM, EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM, EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS) static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { Loading crypto/evp/evp.h +10 −0 Original line number Diff line number Diff line Loading @@ -391,6 +391,16 @@ struct evp_cipher_st #define EVP_CTRL_AEAD_TLS1_AAD 0x16 /* Used by composite AEAD ciphers, no-op in GCM, CCM... */ #define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 /* Set the GCM invocation field, decrypt only */ #define EVP_CTRL_GCM_SET_IV_INV 0x18 /* GCM TLS constants */ /* Length of fixed part of IV derived from PRF */ #define EVP_GCM_TLS_FIXED_IV_LEN 4 /* Length of explicit part of IV part of TLS records */ #define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 /* Length of tag for TLS */ #define EVP_GCM_TLS_TAG_LEN 16 typedef struct evp_cipher_info_st { Loading ssl/s3_lib.c +324 −0 Original line number Diff line number Diff line Loading @@ -1823,6 +1823,200 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ #endif /* OPENSSL_NO_SEED */ /* GCM ciphersuites from RFC5288 */ /* Cipher 9C */ { 1, TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, SSL_kRSA, SSL_aRSA, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher 9D */ { 1, TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, SSL_kRSA, SSL_aRSA, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher 9E */ { 1, TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kEDH, SSL_aRSA, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher 9F */ { 1, TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kEDH, SSL_aRSA, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher A0 */ { 0, TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256, SSL_kDHr, SSL_aDH, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher A1 */ { 0, TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384, SSL_kDHr, SSL_aDH, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher A2 */ { 1, TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256, SSL_kEDH, SSL_aDSS, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher A3 */ { 1, TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384, SSL_kEDH, SSL_aDSS, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher A4 */ { 0, TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256, TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256, SSL_kDHr, SSL_aDH, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher A5 */ { 0, TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384, TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384, SSL_kDHr, SSL_aDH, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher A6 */ { 1, TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256, TLS1_CK_ADH_WITH_AES_128_GCM_SHA256, SSL_kEDH, SSL_aNULL, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher A7 */ { 1, TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384, TLS1_CK_ADH_WITH_AES_256_GCM_SHA384, SSL_kEDH, SSL_aNULL, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, #ifndef OPENSSL_NO_ECDH /* Cipher C001 */ { Loading Loading @@ -2502,6 +2696,136 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 256, }, /* GCM based TLS v1.2 ciphersuites from RFC5289 */ /* Cipher C02B */ { 1, TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kEECDH, SSL_aECDSA, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher C02C */ { 1, TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kEECDH, SSL_aECDSA, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher C02D */ { 1, TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kECDHe, SSL_aECDH, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher C02E */ { 1, TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kECDHe, SSL_aECDH, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher C02F */ { 1, TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kEECDH, SSL_aRSA, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher C030 */ { 1, TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kEECDH, SSL_aRSA, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher C031 */ { 1, TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256, SSL_kECDHe, SSL_aECDH, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher C032 */ { 1, TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384, SSL_kECDHe, SSL_aECDH, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, #endif /* OPENSSL_NO_ECDH */ Loading Loading
CHANGES +11 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,17 @@ Changes between 1.0.1 and 1.1.0 [xx XXX xxxx] *) Add GCM support to TLS library. Some custom code is needed to split the IV between the fixed (from PRF) and explicit (from TLS record) portions. This adds all GCM ciphersuites supported by RFC5288 and RFC5289. Generalise some AES* cipherstrings to inlclude GCM and add a special AESGCM string for GCM only. [Steve Henson] *) Expand range of ctrls for AES GCM. Permit setting invocation field on decrypt and retrieval of invocation field only on encrypt. [Steve Henson] *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support. As required by RFC5289 these ciphersuites cannot be used if for versions of TLS earlier than 1.2. Loading
crypto/evp/c_allc.c +3 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_aes_128_cfb8()); EVP_add_cipher(EVP_aes_128_ofb()); EVP_add_cipher(EVP_aes_128_ctr()); EVP_add_cipher(EVP_aes_128_gcm()); EVP_add_cipher_alias(SN_aes_128_cbc,"AES128"); EVP_add_cipher_alias(SN_aes_128_cbc,"aes128"); EVP_add_cipher(EVP_aes_192_ecb()); Loading @@ -176,6 +177,7 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_aes_192_cfb8()); EVP_add_cipher(EVP_aes_192_ofb()); EVP_add_cipher(EVP_aes_192_ctr()); EVP_add_cipher(EVP_aes_192_gcm()); EVP_add_cipher_alias(SN_aes_192_cbc,"AES192"); EVP_add_cipher_alias(SN_aes_192_cbc,"aes192"); EVP_add_cipher(EVP_aes_256_ecb()); Loading @@ -185,6 +187,7 @@ void OpenSSL_add_all_ciphers(void) EVP_add_cipher(EVP_aes_256_cfb8()); EVP_add_cipher(EVP_aes_256_ofb()); EVP_add_cipher(EVP_aes_256_ctr()); EVP_add_cipher(EVP_aes_256_gcm()); EVP_add_cipher_alias(SN_aes_256_cbc,"AES256"); EVP_add_cipher_alias(SN_aes_256_cbc,"aes256"); #endif Loading
crypto/evp/e_aes.c +108 −6 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ typedef struct int ivlen; /* IV length */ int taglen; int iv_gen; /* It is OK to generate IVs */ int tls_aad_len; /* TLS AAD length */ } EVP_AES_GCM_CTX; typedef struct Loading Loading @@ -748,6 +749,7 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; gctx->tls_aad_len = -1; return 1; case EVP_CTRL_GCM_SET_IVLEN: Loading Loading @@ -798,7 +800,8 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) return 0; if (arg) memcpy(gctx->iv, ptr, arg); if (RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) if (c->encrypt && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) return 0; gctx->iv_gen = 1; return 1; Loading @@ -807,7 +810,9 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) if (gctx->iv_gen == 0 || gctx->key_set == 0) return 0; CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); memcpy(ptr, gctx->iv, gctx->ivlen); if (arg <= 0 || arg > gctx->ivlen) arg = gctx->ivlen; memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); /* Invocation field will be at least 8 bytes in size and * so no need to check wrap around or increment more than * last 8 bytes. Loading @@ -816,6 +821,33 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) gctx->iv_set = 1; return 1; case EVP_CTRL_GCM_SET_IV_INV: if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) return 0; memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); gctx->iv_set = 1; return 1; case EVP_CTRL_AEAD_TLS1_AAD: /* Save the AAD for later use */ if (arg != 13) return 0; memcpy(c->buf, ptr, arg); gctx->tls_aad_len = arg; { unsigned int len=c->buf[arg-2]<<8|c->buf[arg-1]; /* Correct length for explicit IV */ len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!c->encrypt) len -= EVP_GCM_TLS_TAG_LEN; c->buf[arg-2] = len>>8; c->buf[arg-1] = len & 0xff; } /* Extra padding: tag appended to record */ return EVP_GCM_TLS_TAG_LEN; default: return -1; Loading Loading @@ -857,12 +889,79 @@ static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 1; } /* Handle TLS GCM packet format. This consists of the last portion of the IV * followed by the payload and finally the tag. On encrypt generate IV, * encrypt payload and write the tag. On verify retrieve IV, decrypt payload * and verify tag. */ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_GCM_CTX *gctx = ctx->cipher_data; int rv = -1; /* Encrypt/decrypt must be performed in place */ if (out != in) return -1; /* Set IV from start of buffer or generate IV and write to start * of buffer. */ if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) goto err; /* Use saved AAD */ if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) goto err; /* Fix buffer and length to point to payload */ in += EVP_GCM_TLS_EXPLICIT_IV_LEN; out += EVP_GCM_TLS_EXPLICIT_IV_LEN; len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; if (ctx->encrypt) { /* Encrypt payload */ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) goto err; out += len; /* Finally write tag */ CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; } else { /* Decrypt */ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) goto err; /* Retrieve tag */ CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); /* If tag mismatch wipe buffer */ if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { OPENSSL_cleanse(out, len); goto err; } rv = len; } err: gctx->iv_set = 0; gctx->tls_aad_len = -1; return rv; } static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_GCM_CTX *gctx = ctx->cipher_data; /* If not set up, return error */ if (!gctx->iv_set && !gctx->key_set) if (!gctx->key_set) return -1; if (gctx->tls_aad_len >= 0) return aes_gcm_tls_cipher(ctx, out, in, len); if (!gctx->iv_set) return -1; if (!ctx->encrypt && gctx->taglen < 0) return -1; Loading Loading @@ -908,9 +1007,12 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT) BLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,128,1,12,gcm,GCM, EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,192,1,12,gcm,GCM, EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes,256,1,12,gcm,GCM, EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_AEAD_CIPHER|CUSTOM_FLAGS) static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { Loading
crypto/evp/evp.h +10 −0 Original line number Diff line number Diff line Loading @@ -391,6 +391,16 @@ struct evp_cipher_st #define EVP_CTRL_AEAD_TLS1_AAD 0x16 /* Used by composite AEAD ciphers, no-op in GCM, CCM... */ #define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 /* Set the GCM invocation field, decrypt only */ #define EVP_CTRL_GCM_SET_IV_INV 0x18 /* GCM TLS constants */ /* Length of fixed part of IV derived from PRF */ #define EVP_GCM_TLS_FIXED_IV_LEN 4 /* Length of explicit part of IV part of TLS records */ #define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 /* Length of tag for TLS */ #define EVP_GCM_TLS_TAG_LEN 16 typedef struct evp_cipher_info_st { Loading
ssl/s3_lib.c +324 −0 Original line number Diff line number Diff line Loading @@ -1823,6 +1823,200 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ #endif /* OPENSSL_NO_SEED */ /* GCM ciphersuites from RFC5288 */ /* Cipher 9C */ { 1, TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, SSL_kRSA, SSL_aRSA, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher 9D */ { 1, TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, SSL_kRSA, SSL_aRSA, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher 9E */ { 1, TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kEDH, SSL_aRSA, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher 9F */ { 1, TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kEDH, SSL_aRSA, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher A0 */ { 0, TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256, SSL_kDHr, SSL_aDH, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher A1 */ { 0, TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384, SSL_kDHr, SSL_aDH, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher A2 */ { 1, TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256, TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256, SSL_kEDH, SSL_aDSS, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher A3 */ { 1, TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384, SSL_kEDH, SSL_aDSS, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher A4 */ { 0, TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256, TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256, SSL_kDHr, SSL_aDH, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher A5 */ { 0, TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384, TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384, SSL_kDHr, SSL_aDH, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher A6 */ { 1, TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256, TLS1_CK_ADH_WITH_AES_128_GCM_SHA256, SSL_kEDH, SSL_aNULL, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher A7 */ { 1, TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384, TLS1_CK_ADH_WITH_AES_256_GCM_SHA384, SSL_kEDH, SSL_aNULL, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, #ifndef OPENSSL_NO_ECDH /* Cipher C001 */ { Loading Loading @@ -2502,6 +2696,136 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[]={ 256, }, /* GCM based TLS v1.2 ciphersuites from RFC5289 */ /* Cipher C02B */ { 1, TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kEECDH, SSL_aECDSA, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher C02C */ { 1, TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kEECDH, SSL_aECDSA, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher C02D */ { 1, TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kECDHe, SSL_aECDH, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher C02E */ { 1, TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kECDHe, SSL_aECDH, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher C02F */ { 1, TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kEECDH, SSL_aRSA, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher C030 */ { 1, TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kEECDH, SSL_aRSA, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, /* Cipher C031 */ { 1, TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256, SSL_kECDHe, SSL_aECDH, SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256, 128, 128, }, /* Cipher C032 */ { 1, TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384, SSL_kECDHe, SSL_aECDH, SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_NOT_EXP|SSL_HIGH|SSL_FIPS, SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384, 256, 256, }, #endif /* OPENSSL_NO_ECDH */ Loading