From e75c5a794e71baa3d76214be3ac8dc6e082e4a1a Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Fri, 31 Jul 2015 16:54:35 +0100 Subject: CCM support. Reviewed-by: Tim Hudson --- ssl/record/rec_layer_d1.c | 2 ++ ssl/record/rec_layer_s3.c | 2 ++ ssl/record/ssl3_record.c | 14 ++++++++++---- ssl/ssl_algs.c | 2 ++ ssl/ssl_ciph.c | 24 ++++++++++++++++++------ ssl/ssl_locl.h | 4 +++- ssl/t1_enc.c | 14 +++++++++++++- 7 files changed, 50 insertions(+), 12 deletions(-) (limited to 'ssl') diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index 3da4f116bb..74796bed6f 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -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 diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index 8a9e30302d..5b286630ac 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -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 diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index 1865f24241..1fa1710326 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -764,10 +764,16 @@ int tls1_enc(SSL *s, int send) ? (i < 0) : (i == 0)) return -1; /* AEAD can fail to verify MAC */ - if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send) { - rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + if (send == 0) { + if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE) { + rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + } else if (EVP_CIPHER_mode(enc) == EVP_CIPH_CCM_MODE) { + rec->data += EVP_CCM_TLS_EXPLICIT_IV_LEN; + rec->input += EVP_CCM_TLS_EXPLICIT_IV_LEN; + rec->length -= EVP_CCM_TLS_EXPLICIT_IV_LEN; + } } ret = 1; diff --git a/ssl/ssl_algs.c b/ssl/ssl_algs.c index ba9fc48a8d..f4827fd787 100644 --- a/ssl/ssl_algs.c +++ b/ssl/ssl_algs.c @@ -91,6 +91,8 @@ int SSL_library_init(void) EVP_add_cipher(EVP_aes_256_cbc()); EVP_add_cipher(EVP_aes_128_gcm()); EVP_add_cipher(EVP_aes_256_gcm()); + EVP_add_cipher(EVP_aes_128_ccm()); + EVP_add_cipher(EVP_aes_256_ccm()); EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 08a95f958b..7f2970b317 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -164,7 +164,9 @@ #define SSL_ENC_SEED_IDX 11 #define SSL_ENC_AES128GCM_IDX 12 #define SSL_ENC_AES256GCM_IDX 13 -#define SSL_ENC_NUM_IDX 14 +#define SSL_ENC_AES128CCM_IDX 14 +#define SSL_ENC_AES256CCM_IDX 15 +#define SSL_ENC_NUM_IDX 16 /* NB: make sure indices in these tables match values above */ @@ -188,7 +190,9 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = { {SSL_eGOST2814789CNT, NID_gost89_cnt}, /* SSL_ENC_GOST89_IDX 10 */ {SSL_SEED, NID_seed_cbc}, /* SSL_ENC_SEED_IDX 11 */ {SSL_AES128GCM, NID_aes_128_gcm}, /* SSL_ENC_AES128GCM_IDX 12 */ - {SSL_AES256GCM, NID_aes_256_gcm} /* SSL_ENC_AES256GCM_IDX 13 */ + {SSL_AES256GCM, NID_aes_256_gcm}, /* SSL_ENC_AES256GCM_IDX 13 */ + {SSL_AES128CCM, NID_aes_128_ccm}, /* SSL_ENC_AES128CCM_IDX 14 */ + {SSL_AES256CCM, NID_aes_256_ccm} /* SSL_ENC_AES256CCM_IDX 15 */ }; static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = { @@ -355,13 +359,15 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_IDEA, 0, 0, 0, SSL_IDEA, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_SEED, 0, 0, 0, SSL_SEED, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_eNULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_AES128, 0, 0, 0, SSL_AES128 | SSL_AES128GCM, 0, 0, 0, 0, 0, - 0}, - {0, SSL_TXT_AES256, 0, 0, 0, SSL_AES256 | SSL_AES256GCM, 0, 0, 0, 0, 0, - 0}, + {0, SSL_TXT_AES128, 0, 0, 0, SSL_AES128 | SSL_AES128GCM | SSL_AES128CCM, 0, + 0, 0, 0, 0, 0}, + {0, SSL_TXT_AES256, 0, 0, 0, SSL_AES256 | SSL_AES256GCM | SSL_AES256CCM, 0, + 0, 0, 0, 0, 0}, {0, SSL_TXT_AES, 0, 0, 0, SSL_AES, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_AES_GCM, 0, 0, 0, SSL_AES128GCM | SSL_AES256GCM, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_AES_CCM, 0, 0, 0, SSL_AES128CCM | SSL_AES256CCM, 0, 0, 0, 0, + 0, 0}, {0, SSL_TXT_CAMELLIA128, 0, 0, 0, SSL_CAMELLIA128, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_CAMELLIA256, 0, 0, 0, SSL_CAMELLIA256, 0, 0, 0, 0, 0, 0}, {0, SSL_TXT_CAMELLIA, 0, 0, 0, SSL_CAMELLIA128 | SSL_CAMELLIA256, 0, 0, 0, @@ -1709,6 +1715,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_AES256GCM: enc = "AESGCM(256)"; break; + case SSL_AES128CCM: + enc = "AESCCM(128)"; + break; + case SSL_AES256CCM: + enc = "AESCCM(256)"; + break; case SSL_CAMELLIA128: enc = "Camellia(128)"; break; diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 63b547a8f9..b30a635e79 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -359,8 +359,10 @@ # define SSL_SEED 0x00000800L # define SSL_AES128GCM 0x00001000L # define SSL_AES256GCM 0x00002000L +# define SSL_AES128CCM 0x00004000L +# define SSL_AES256CCM 0x00008000L -# define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM) +# define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM|SSL_AES128CCM|SSL_AES256CCM) # define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) /* Bits for algorithm_mac (symmetric authentication) */ diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 9942bb433f..87de2fe6c5 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -422,9 +422,11 @@ int tls1_change_cipher_state(SSL *s, int which) j = is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ - /* If GCM mode only part of IV comes from PRF */ + /* If GCM/CCM mode only part of IV comes from PRF */ if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) k = EVP_GCM_TLS_FIXED_IV_LEN; + else if (EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE) + k = EVP_CCM_TLS_FIXED_IV_LEN; else k = EVP_CIPHER_iv_length(c); if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || @@ -506,6 +508,16 @@ int tls1_change_cipher_state(SSL *s, int which) SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); goto err2; } + } else if (EVP_CIPHER_mode(c) == EVP_CIPH_CCM_MODE) { + int taglen = 16; + if (!EVP_CipherInit_ex(dd, c, NULL, NULL, NULL, (which & SSL3_CC_WRITE)) + || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_IVLEN, 12, NULL) + || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_TAG, taglen, NULL) + || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_CCM_SET_IV_FIXED, k, iv) + || !EVP_CipherInit_ex(dd, NULL, NULL, key, NULL, -1)) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } } else { if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); -- cgit v1.2.3