Loading crypto/evp/e_aes.c +88 −4 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ typedef struct { int tag_set; /* Set if tag is valid */ int len_set; /* Set if message length set */ int L, M; /* L and M parameters from RFC3610 */ int tls_aad_len; /* TLS AAD length */ CCM128_CONTEXT ccm; ccm128_f str; } EVP_AES_CCM_CTX; Loading Loading @@ -1853,6 +1854,34 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) cctx->M = 12; cctx->tag_set = 0; cctx->len_set = 0; cctx->tls_aad_len = -1; return 1; case EVP_CTRL_AEAD_TLS1_AAD: /* Save the AAD for later use */ if (arg != EVP_AEAD_TLS1_AAD_LEN) return 0; memcpy(c->buf, ptr, arg); cctx->tls_aad_len = arg; { uint16_t len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; /* Correct length for explicit IV */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!c->encrypt) len -= cctx->M; c->buf[arg - 2] = len >> 8; c->buf[arg - 1] = len & 0xff; } /* Extra padding: tag appended to record */ return cctx->M; case EVP_CTRL_CCM_SET_IV_FIXED: /* Sanity check length */ if (arg != EVP_CCM_TLS_FIXED_IV_LEN) return 0; /* Just copy to first part of IV */ memcpy(c->iv, ptr, arg); return 1; case EVP_CTRL_AEAD_SET_IVLEN: Loading Loading @@ -1945,14 +1974,66 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 1; } static int aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_CCM_CTX *cctx = ctx->cipher_data; CCM128_CONTEXT *ccm = &cctx->ccm; /* Encrypt/decrypt must be performed in place */ if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M)) return -1; /* If encrypting set explicit IV from sequence number (start of AAD) */ if (ctx->encrypt) memcpy(out, ctx->buf, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Get rest of IV from explicit IV */ memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Correct length value */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; /* Use saved AAD */ CRYPTO_ccm128_aad(ccm, ctx->buf, cctx->tls_aad_len); /* Fix buffer to point to payload */ in += EVP_CCM_TLS_EXPLICIT_IV_LEN; out += EVP_CCM_TLS_EXPLICIT_IV_LEN; if (ctx->encrypt) { if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) : CRYPTO_ccm128_encrypt(ccm, in, out, len)) return -1; if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M)) return -1; return len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; } else { if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, cctx->str) : !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { unsigned char tag[16]; if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { if (!CRYPTO_memcmp(tag, in + len, cctx->M)) return len; } } OPENSSL_cleanse(out, len); return -1; } } static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_CCM_CTX *cctx = ctx->cipher_data; CCM128_CONTEXT *ccm = &cctx->ccm; /* If not set up, return error */ if (!cctx->iv_set && !cctx->key_set) if (!cctx->key_set) return -1; if (cctx->tls_aad_len >= 0) return aes_ccm_tls_cipher(ctx, out, in, len); if (!cctx->iv_set) return -1; if (!ctx->encrypt && !cctx->tag_set) return -1; if (!out) { Loading Loading @@ -2007,9 +2088,12 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, # define aes_ccm_cleanup NULL BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) typedef struct { union { Loading include/openssl/evp.h +9 −1 Original line number Diff line number Diff line Loading @@ -399,14 +399,16 @@ struct evp_cipher_st { # define EVP_CTRL_AEAD_SET_IVLEN 0x9 # define EVP_CTRL_AEAD_GET_TAG 0x10 # define EVP_CTRL_AEAD_SET_TAG 0x11 # define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 # define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN # define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG # define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG # define EVP_CTRL_GCM_SET_IV_FIXED 0x12 # define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED # define EVP_CTRL_GCM_IV_GEN 0x13 # define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN # define EVP_CTRL_CCM_GET_TAG EVP_CTRL_AEAD_GET_TAG # define EVP_CTRL_CCM_SET_TAG EVP_CTRL_AEAD_SET_TAG # define EVP_CTRL_CCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED # define EVP_CTRL_CCM_SET_L 0x14 # define EVP_CTRL_CCM_SET_MSGLEN 0x15 /* Loading Loading @@ -443,6 +445,12 @@ typedef struct { /* Length of tag for TLS */ # define EVP_GCM_TLS_TAG_LEN 16 /* CCM TLS constants */ /* Length of fixed part of IV derived from PRF */ # define EVP_CCM_TLS_FIXED_IV_LEN 4 /* Length of explicit part of IV part of TLS records */ # define EVP_CCM_TLS_EXPLICIT_IV_LEN 8 typedef struct evp_cipher_info_st { const EVP_CIPHER *cipher; unsigned char iv[EVP_MAX_IV_LENGTH]; Loading include/openssl/ssl.h +1 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,7 @@ extern "C" { # define SSL_TXT_AES256 "AES256" # define SSL_TXT_AES "AES" # define SSL_TXT_AES_GCM "AESGCM" # define SSL_TXT_AES_CCM "AESCCM" # define SSL_TXT_CAMELLIA128 "CAMELLIA128" # define SSL_TXT_CAMELLIA256 "CAMELLIA256" # define SSL_TXT_CAMELLIA "CAMELLIA" Loading ssl/record/rec_layer_d1.c +2 −0 Original line number Diff line number Diff line Loading @@ -1120,6 +1120,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, /* Need explicit part of IV for GCM mode */ else if (mode == EVP_CIPH_GCM_MODE) eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; else if (mode == EVP_CIPH_CCM_MODE) eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; else eivlen = 0; } else Loading ssl/record/rec_layer_s3.c +2 −0 Original line number Diff line number Diff line Loading @@ -799,6 +799,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* Need explicit part of IV for GCM mode */ else if (mode == EVP_CIPH_GCM_MODE) eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; else if (mode == EVP_CIPH_CCM_MODE) eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; else eivlen = 0; } else Loading Loading
crypto/evp/e_aes.c +88 −4 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ typedef struct { int tag_set; /* Set if tag is valid */ int len_set; /* Set if message length set */ int L, M; /* L and M parameters from RFC3610 */ int tls_aad_len; /* TLS AAD length */ CCM128_CONTEXT ccm; ccm128_f str; } EVP_AES_CCM_CTX; Loading Loading @@ -1853,6 +1854,34 @@ static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) cctx->M = 12; cctx->tag_set = 0; cctx->len_set = 0; cctx->tls_aad_len = -1; return 1; case EVP_CTRL_AEAD_TLS1_AAD: /* Save the AAD for later use */ if (arg != EVP_AEAD_TLS1_AAD_LEN) return 0; memcpy(c->buf, ptr, arg); cctx->tls_aad_len = arg; { uint16_t len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; /* Correct length for explicit IV */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ if (!c->encrypt) len -= cctx->M; c->buf[arg - 2] = len >> 8; c->buf[arg - 1] = len & 0xff; } /* Extra padding: tag appended to record */ return cctx->M; case EVP_CTRL_CCM_SET_IV_FIXED: /* Sanity check length */ if (arg != EVP_CCM_TLS_FIXED_IV_LEN) return 0; /* Just copy to first part of IV */ memcpy(c->iv, ptr, arg); return 1; case EVP_CTRL_AEAD_SET_IVLEN: Loading Loading @@ -1945,14 +1974,66 @@ static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, return 1; } static int aes_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_CCM_CTX *cctx = ctx->cipher_data; CCM128_CONTEXT *ccm = &cctx->ccm; /* Encrypt/decrypt must be performed in place */ if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M)) return -1; /* If encrypting set explicit IV from sequence number (start of AAD) */ if (ctx->encrypt) memcpy(out, ctx->buf, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Get rest of IV from explicit IV */ memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Correct length value */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) return -1; /* Use saved AAD */ CRYPTO_ccm128_aad(ccm, ctx->buf, cctx->tls_aad_len); /* Fix buffer to point to payload */ in += EVP_CCM_TLS_EXPLICIT_IV_LEN; out += EVP_CCM_TLS_EXPLICIT_IV_LEN; if (ctx->encrypt) { if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) : CRYPTO_ccm128_encrypt(ccm, in, out, len)) return -1; if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M)) return -1; return len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; } else { if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, cctx->str) : !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { unsigned char tag[16]; if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { if (!CRYPTO_memcmp(tag, in + len, cctx->M)) return len; } } OPENSSL_cleanse(out, len); return -1; } } static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_AES_CCM_CTX *cctx = ctx->cipher_data; CCM128_CONTEXT *ccm = &cctx->ccm; /* If not set up, return error */ if (!cctx->iv_set && !cctx->key_set) if (!cctx->key_set) return -1; if (cctx->tls_aad_len >= 0) return aes_ccm_tls_cipher(ctx, out, in, len); if (!cctx->iv_set) return -1; if (!ctx->encrypt && !cctx->tag_set) return -1; if (!out) { Loading Loading @@ -2007,9 +2088,12 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, # define aes_ccm_cleanup NULL BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, EVP_CIPH_FLAG_AEAD_CIPHER | CUSTOM_FLAGS) typedef struct { union { Loading
include/openssl/evp.h +9 −1 Original line number Diff line number Diff line Loading @@ -399,14 +399,16 @@ struct evp_cipher_st { # define EVP_CTRL_AEAD_SET_IVLEN 0x9 # define EVP_CTRL_AEAD_GET_TAG 0x10 # define EVP_CTRL_AEAD_SET_TAG 0x11 # define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 # define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN # define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG # define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG # define EVP_CTRL_GCM_SET_IV_FIXED 0x12 # define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED # define EVP_CTRL_GCM_IV_GEN 0x13 # define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN # define EVP_CTRL_CCM_GET_TAG EVP_CTRL_AEAD_GET_TAG # define EVP_CTRL_CCM_SET_TAG EVP_CTRL_AEAD_SET_TAG # define EVP_CTRL_CCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED # define EVP_CTRL_CCM_SET_L 0x14 # define EVP_CTRL_CCM_SET_MSGLEN 0x15 /* Loading Loading @@ -443,6 +445,12 @@ typedef struct { /* Length of tag for TLS */ # define EVP_GCM_TLS_TAG_LEN 16 /* CCM TLS constants */ /* Length of fixed part of IV derived from PRF */ # define EVP_CCM_TLS_FIXED_IV_LEN 4 /* Length of explicit part of IV part of TLS records */ # define EVP_CCM_TLS_EXPLICIT_IV_LEN 8 typedef struct evp_cipher_info_st { const EVP_CIPHER *cipher; unsigned char iv[EVP_MAX_IV_LENGTH]; Loading
include/openssl/ssl.h +1 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,7 @@ extern "C" { # define SSL_TXT_AES256 "AES256" # define SSL_TXT_AES "AES" # define SSL_TXT_AES_GCM "AESGCM" # define SSL_TXT_AES_CCM "AESCCM" # define SSL_TXT_CAMELLIA128 "CAMELLIA128" # define SSL_TXT_CAMELLIA256 "CAMELLIA256" # define SSL_TXT_CAMELLIA "CAMELLIA" Loading
ssl/record/rec_layer_d1.c +2 −0 Original line number Diff line number Diff line Loading @@ -1120,6 +1120,8 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, /* Need explicit part of IV for GCM mode */ else if (mode == EVP_CIPH_GCM_MODE) eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; else if (mode == EVP_CIPH_CCM_MODE) eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; else eivlen = 0; } else Loading
ssl/record/rec_layer_s3.c +2 −0 Original line number Diff line number Diff line Loading @@ -799,6 +799,8 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, /* Need explicit part of IV for GCM mode */ else if (mode == EVP_CIPH_GCM_MODE) eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; else if (mode == EVP_CIPH_CCM_MODE) eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN; else eivlen = 0; } else Loading