From ccff37f4b1fa1e9bbc680c355eb26cab29210b21 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 15 Jan 2013 15:20:30 -0800 Subject: [PATCH] added TLS support for AES-CCM-8 --- configure.ac | 9 ++- ctaocrypt/src/aes.c | 4 +- cyassl/internal.h | 27 +++++--- src/internal.c | 148 +++++++++++++++++++++++++++++++++++------ src/keys.c | 103 ++++++++++++++++++++++------ src/ssl.c | 5 ++ tests/include.am | 1 + tests/suites.c | 11 +++ tests/test-aesccm.conf | 16 +++++ 9 files changed, 274 insertions(+), 50 deletions(-) create mode 100644 tests/test-aesccm.conf diff --git a/configure.ac b/configure.ac index 9785389d6..0c6703f38 100644 --- a/configure.ac +++ b/configure.ac @@ -339,10 +339,10 @@ AC_ARG_ENABLE([aesccm], if test "$ENABLED_AESCCM" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DHAVE_AESCCM" + AM_CFLAGS="$AM_CFLAGS -DHAVE_AESCCM -DCYASSL_SHA384 -DCYASSL_SHA512" fi -AM_CONDITIONAL([BUILD_AESGCM], [test "x$ENABLED_AESGCM" = "xyes"]) +AM_CONDITIONAL([BUILD_AESCCM], [test "x$ENABLED_AESCCM" = "xyes"]) # AES-NI @@ -422,6 +422,11 @@ then ENABLED_SHA512="yes" fi +if test "$ENABLED_AESCCM" = "yes" +then + ENABLED_SHA512="yes" +fi + AM_CONDITIONAL([BUILD_SHA512], [test "x$ENABLED_SHA512" = "xyes"]) diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index fb4149b09..c67e95ded 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -2660,10 +2660,12 @@ int AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, oSz = inSz; XMEMCPY(B+1, nonce, AES_BLOCK_SIZE); lenSz = AES_BLOCK_SIZE - 1 - nonceSz; + B[0] = (lenSz - 1); - for (i = 0; i < lenSz - 1; i++) + for (i = 0; i < lenSz; i++) B[AES_BLOCK_SIZE - 1 - i] = 0; B[15] = 1; + while (oSz >= AES_BLOCK_SIZE) { AesEncrypt(aes, B, A); xorbuf(A, in, AES_BLOCK_SIZE); diff --git a/cyassl/internal.h b/cyassl/internal.h index d2cc3e61e..45eba0a69 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -162,6 +162,10 @@ void c32to24(word32 in, word24 out); #define BUILD_TLS_RSA_WITH_AES_128_GCM_SHA256 #define BUILD_TLS_RSA_WITH_AES_256_GCM_SHA384 #endif + #if defined (HAVE_AESCCM) + #define BUILD_TLS_RSA_WITH_AES_128_CCM_8_SHA256 + #define BUILD_TLS_RSA_WITH_AES_256_CCM_8_SHA384 + #endif #endif #if !defined(NO_PSK) && !defined(NO_AES) && !defined(NO_TLS) @@ -357,7 +361,14 @@ enum { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0x2f, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0x30, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0x31, - TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0x32 + TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0x32, + + /* AES-CCM, first byte is 0xC0 but isn't ECC, + * also, in some of the other AES-CCM suites + * there will be second byte number conflicts + * with non-ECC AES-GCM */ + TLS_RSA_WITH_AES_128_CCM_8_SHA256 = 0xa0, + TLS_RSA_WITH_AES_256_CCM_8_SHA384 = 0xa1 }; @@ -463,9 +474,6 @@ enum Misc { AES_256_KEY_SIZE = 32, /* for 256 bit */ AES_192_KEY_SIZE = 24, /* for 192 bit */ AES_IV_SIZE = 16, /* always block size */ - AES_GCM_IMP_IV_SZ = 4, /* Implicit part of IV */ - AES_GCM_EXP_IV_SZ = 8, /* Explicit part of IV */ - AES_GCM_CTR_IV_SZ = 4, /* Counter part of IV */ AES_128_KEY_SIZE = 16, /* for 128 bit */ AEAD_SEQ_OFFSET = 4, /* Auth Data: Sequence number */ @@ -475,7 +483,9 @@ enum Misc { AEAD_LEN_OFFSET = 11, /* Auth Data: Length */ AEAD_AUTH_TAG_SZ = 16, /* Size of the authentication tag */ AEAD_AUTH_DATA_SZ = 13, /* Size of the data to authenticate */ - AEAD_NONCE_SZ = AES_GCM_EXP_IV_SZ + AES_GCM_IMP_IV_SZ, + AEAD_IMP_IV_SZ = 4, /* Size of the implicit IV */ + AEAD_EXP_IV_SZ = 8, /* Size of the explicit IV */ + AEAD_NONCE_SZ = AEAD_EXP_IV_SZ + AEAD_IMP_IV_SZ, HC_128_KEY_SIZE = 16, /* 128 bits */ HC_128_IV_SIZE = 16, /* also 128 bits */ @@ -970,6 +980,7 @@ enum BulkCipherAlgorithm { idea, aes, aes_gcm, + aes_ccm, hc128, /* CyaSSL extensions */ rabbit }; @@ -1052,9 +1063,9 @@ typedef struct Keys { byte client_write_IV[AES_IV_SIZE]; /* max sizes */ byte server_write_IV[AES_IV_SIZE]; #ifdef HAVE_AEAD - byte aead_exp_IV[AES_GCM_EXP_IV_SZ]; - byte aead_enc_imp_IV[AES_GCM_IMP_IV_SZ]; - byte aead_dec_imp_IV[AES_GCM_IMP_IV_SZ]; + byte aead_exp_IV[AEAD_EXP_IV_SZ]; + byte aead_enc_imp_IV[AEAD_IMP_IV_SZ]; + byte aead_dec_imp_IV[AEAD_IMP_IV_SZ]; #endif word32 peer_sequence_number; diff --git a/src/internal.c b/src/internal.c index c70e06941..0a82b9f72 100644 --- a/src/internal.c +++ b/src/internal.c @@ -767,6 +767,20 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK, } #endif +#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8_SHA256 + if (tls1_2 && haveRSA) { + suites->suites[idx++] = ECC_BYTE; + suites->suites[idx++] = TLS_RSA_WITH_AES_128_CCM_8_SHA256; + } +#endif + +#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8_SHA384 + if (tls1_2 && haveRSA) { + suites->suites[idx++] = ECC_BYTE; + suites->suites[idx++] = TLS_RSA_WITH_AES_256_CCM_8_SHA384; + } +#endif + #ifdef BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 if (tls1_2 && haveDH && haveRSA) { suites->suites[idx++] = 0; @@ -2934,7 +2948,7 @@ static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify) static INLINE void AeadIncrementExpIV(CYASSL* ssl) { int i; - for (i = AES_GCM_EXP_IV_SZ-1; i >= 0; i--) { + for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) { if (++ssl->keys.aead_exp_IV[i]) return; } } @@ -3001,15 +3015,51 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) /* Store the length of the plain text minus the explicit * IV length minus the authentication tag size. */ - c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + c16toa(sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, additional + AEAD_LEN_OFFSET); XMEMCPY(nonce, - ssl->keys.aead_enc_imp_IV, AES_GCM_IMP_IV_SZ); - XMEMCPY(nonce + AES_GCM_IMP_IV_SZ, - ssl->keys.aead_exp_IV, AES_GCM_EXP_IV_SZ); + ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ); + XMEMCPY(nonce + AEAD_IMP_IV_SZ, + ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ); AesGcmEncrypt(ssl->encrypt.aes, - out + AES_GCM_EXP_IV_SZ, input + AES_GCM_EXP_IV_SZ, - sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ, + sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + nonce, AEAD_NONCE_SZ, + out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ, + additional, AEAD_AUTH_DATA_SZ); + AeadIncrementExpIV(ssl); + XMEMSET(nonce, 0, AEAD_NONCE_SZ); + } + break; + #endif + + #ifdef HAVE_AESCCM + case aes_ccm: + { + byte additional[AES_BLOCK_SIZE]; + byte nonce[AEAD_NONCE_SZ]; + + XMEMSET(additional, 0, AES_BLOCK_SIZE); + + /* sequence number field is 64-bits, we only use 32-bits */ + c32toa(GetSEQIncrement(ssl, 0), + additional + AEAD_SEQ_OFFSET); + + /* Store the type, version. Unfortunately, they are in + * the input buffer ahead of the plaintext. */ + XMEMCPY(additional + AEAD_TYPE_OFFSET, input - 5, 3); + + /* Store the length of the plain text minus the explicit + * IV length minus the authentication tag size. */ + c16toa(sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + additional + AEAD_LEN_OFFSET); + XMEMCPY(nonce, + ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ); + XMEMCPY(nonce + AEAD_IMP_IV_SZ, + ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ); + AesCcmEncrypt(ssl->encrypt.aes, + out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ, + sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, nonce, AEAD_NONCE_SZ, out + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ, additional, AEAD_AUTH_DATA_SZ); @@ -3118,14 +3168,14 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; - c16toa(sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + c16toa(sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, additional + AEAD_LEN_OFFSET); - XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AES_GCM_IMP_IV_SZ); - XMEMCPY(nonce + AES_GCM_IMP_IV_SZ, input, AES_GCM_EXP_IV_SZ); + XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ); + XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ); if (AesGcmDecrypt(ssl->decrypt.aes, - plain + AES_GCM_EXP_IV_SZ, - input + AES_GCM_EXP_IV_SZ, - sz - AES_GCM_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + plain + AEAD_EXP_IV_SZ, + input + AEAD_EXP_IV_SZ, + sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, nonce, AEAD_NONCE_SZ, input + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ, additional, AEAD_AUTH_DATA_SZ) < 0) { @@ -3138,6 +3188,42 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, } #endif + #ifdef HAVE_AESCCM + case aes_ccm: + { + byte additional[AES_BLOCK_SIZE]; + byte nonce[AEAD_NONCE_SZ]; + + XMEMSET(additional, 0, AES_BLOCK_SIZE); + + /* sequence number field is 64-bits, we only use 32-bits */ + c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET); + + additional[AEAD_TYPE_OFFSET] = ssl->curRL.type; + additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; + additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; + + c16toa(sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + additional + AEAD_LEN_OFFSET); + XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ); + XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ); + if (AesCcmDecrypt(ssl->decrypt.aes, + plain + AEAD_EXP_IV_SZ, + input + AEAD_EXP_IV_SZ, + sz - AEAD_EXP_IV_SZ - AEAD_AUTH_TAG_SZ, + nonce, AEAD_NONCE_SZ, + input + sz - AEAD_AUTH_TAG_SZ, AEAD_AUTH_TAG_SZ, + additional, AEAD_AUTH_DATA_SZ) < 0) { + /* XXX HERE!@ */ + SendAlert(ssl, alert_fatal, bad_record_mac); + XMEMSET(nonce, 0, AEAD_NONCE_SZ); + return VERIFY_MAC_ERROR; + } + XMEMSET(nonce, 0, AEAD_NONCE_SZ); + break; + } + #endif + #ifdef HAVE_HC128 case hc128: Hc128_Process(ssl->decrypt.hc128, plain, input, sz); @@ -3218,7 +3304,7 @@ static int DecryptMessage(CYASSL* ssl, byte* input, word32 sz, word32* idx) if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) *idx += ssl->specs.block_size; /* go past TLSv1.1 IV */ if (ssl->specs.cipher_type == aead) - *idx += AES_GCM_EXP_IV_SZ; + *idx += AEAD_EXP_IV_SZ; } return decryptResult; @@ -3530,7 +3616,7 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx) } } else if (ssl->specs.cipher_type == aead) { - ivExtra = AES_GCM_EXP_IV_SZ; + ivExtra = AEAD_EXP_IV_SZ; digestSz = AEAD_AUTH_TAG_SZ; } @@ -4168,11 +4254,11 @@ static int BuildMessage(CYASSL* ssl, byte* output, const byte* input, int inSz, sz += pad; } -#ifdef BUILD_AESGCM +#ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead) { - ivSz = AES_GCM_EXP_IV_SZ; + ivSz = AEAD_EXP_IV_SZ; sz += (ivSz + 16 - digestSz); - XMEMCPY(iv, ssl->keys.aead_exp_IV, AES_GCM_EXP_IV_SZ); + XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ); } #endif size = (word16)(sz - headerSz); /* include mac and digest */ @@ -5082,6 +5168,14 @@ const char* const cipher_names[] = "NTRU-AES256-SHA", #endif +#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8_SHA256 + "AES128-CCM-8-SHA256", +#endif + +#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8_SHA384 + "AES256-CCM-8-SHA384", +#endif + #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA", #endif @@ -5302,6 +5396,14 @@ int cipher_name_idx[] = TLS_NTRU_RSA_WITH_AES_256_CBC_SHA, #endif +#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8_SHA256 + TLS_RSA_WITH_AES_128_CCM_8_SHA256, +#endif + +#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8_SHA384 + TLS_RSA_WITH_AES_256_CCM_8_SHA384, +#endif + #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, #endif @@ -5474,7 +5576,7 @@ int SetCipherList(Suites* s, const char* list) for (i = 0; i < suiteSz; i++) if (XSTRNCMP(name, cipher_names[i], sizeof(name)) == 0) { - if (XSTRSTR(name, "EC")) + if (XSTRSTR(name, "EC") || XSTRSTR(name, "CCM")) s->suites[idx++] = ECC_BYTE; /* ECC suite */ else s->suites[idx++] = 0x00; /* normal */ @@ -7291,6 +7393,14 @@ int SetCipherList(Suites* s, const char* list) return 1; break; + case TLS_RSA_WITH_AES_128_CCM_8_SHA256 : + case TLS_RSA_WITH_AES_256_CCM_8_SHA384 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_RSA_SIG) + return 1; + break; + default: CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC"); return 0; diff --git a/src/keys.c b/src/keys.c index db8147766..2ab48a93c 100644 --- a/src/keys.c +++ b/src/keys.c @@ -37,12 +37,13 @@ int SetCipherSpecs(CYASSL* ssl) { -#ifdef HAVE_ECC - /* ECC extensions */ + /* ECC extensions, or AES-CCM */ if (ssl->options.cipherSuite0 == ECC_BYTE) { switch (ssl->options.cipherSuite) { +#ifdef HAVE_ECC + #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA : ssl->specs.bulk_cipher_algorithm = aes; @@ -327,7 +328,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 0; ssl->specs.key_size = AES_128_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -344,7 +345,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 0; ssl->specs.key_size = AES_256_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -361,7 +362,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 0; ssl->specs.key_size = AES_128_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -378,7 +379,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 0; ssl->specs.key_size = AES_256_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -395,7 +396,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 1; ssl->specs.key_size = AES_128_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -412,7 +413,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 1; ssl->specs.key_size = AES_256_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -429,7 +430,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 1; ssl->specs.key_size = AES_128_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -446,17 +447,49 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 1; ssl->specs.key_size = AES_256_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif +#endif /* HAVE_ECC */ + +#ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8_SHA256 + case TLS_RSA_WITH_AES_128_CCM_8_SHA256 : + ssl->specs.bulk_cipher_algorithm = aes_ccm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = rsa_kea; + ssl->specs.sig_algo = rsa_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_128_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + break; +#endif + +#ifdef BUILD_TLS_RSA_WITH_AES_256_CCM_8_SHA384 + case TLS_RSA_WITH_AES_256_CCM_8_SHA384 : + ssl->specs.bulk_cipher_algorithm = aes_ccm; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha384_mac; + ssl->specs.kea = rsa_kea; + ssl->specs.sig_algo = rsa_sa_algo; + ssl->specs.hash_size = SHA384_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = AES_256_KEY_SIZE; + ssl->specs.block_size = AES_BLOCK_SIZE; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; + break; +#endif default: CYASSL_MSG("Unsupported cipher suite, SetCipherSpecs ECC"); return UNSUPPORTED_SUITE; } /* switch */ } /* if */ -#endif /* HAVE_ECC */ if (ssl->options.cipherSuite0 != ECC_BYTE) { /* normal suites */ switch (ssl->options.cipherSuite) { @@ -881,7 +914,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 0; ssl->specs.key_size = AES_128_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -898,7 +931,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 0; ssl->specs.key_size = AES_256_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -915,7 +948,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 0; ssl->specs.key_size = AES_128_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -932,7 +965,7 @@ int SetCipherSpecs(CYASSL* ssl) ssl->specs.static_ecdh = 0; ssl->specs.key_size = AES_256_KEY_SIZE; ssl->specs.block_size = AES_BLOCK_SIZE; - ssl->specs.iv_size = AES_GCM_IMP_IV_SZ; + ssl->specs.iv_size = AEAD_IMP_IV_SZ; break; #endif @@ -1146,18 +1179,48 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, if (side == CLIENT_END) { AesGcmSetKey(enc->aes, keys->client_write_key, specs->key_size); XMEMCPY(keys->aead_enc_imp_IV, - keys->client_write_IV, AES_GCM_IMP_IV_SZ); + keys->client_write_IV, AEAD_IMP_IV_SZ); AesGcmSetKey(dec->aes, keys->server_write_key, specs->key_size); XMEMCPY(keys->aead_dec_imp_IV, - keys->server_write_IV, AES_GCM_IMP_IV_SZ); + keys->server_write_IV, AEAD_IMP_IV_SZ); } else { AesGcmSetKey(enc->aes, keys->server_write_key, specs->key_size); XMEMCPY(keys->aead_enc_imp_IV, - keys->server_write_IV, AES_GCM_IMP_IV_SZ); + keys->server_write_IV, AEAD_IMP_IV_SZ); AesGcmSetKey(dec->aes, keys->client_write_key, specs->key_size); XMEMCPY(keys->aead_dec_imp_IV, - keys->client_write_IV, AES_GCM_IMP_IV_SZ); + keys->client_write_IV, AEAD_IMP_IV_SZ); + } + enc->setup = 1; + dec->setup = 1; + } +#endif + +#ifdef HAVE_AESCCM + if (specs->bulk_cipher_algorithm == aes_ccm) { + enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER); + if (enc->aes == NULL) + return MEMORY_E; + dec->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER); + if (dec->aes == NULL) + return MEMORY_E; + + if (side == CLIENT_END) { + AesCcmSetKey(enc->aes, keys->client_write_key, specs->key_size); + XMEMCPY(keys->aead_enc_imp_IV, + keys->client_write_IV, AEAD_IMP_IV_SZ); + AesCcmSetKey(dec->aes, keys->server_write_key, specs->key_size); + XMEMCPY(keys->aead_dec_imp_IV, + keys->server_write_IV, AEAD_IMP_IV_SZ); + } + else { + AesCcmSetKey(enc->aes, keys->server_write_key, specs->key_size); + XMEMCPY(keys->aead_enc_imp_IV, + keys->server_write_IV, AEAD_IMP_IV_SZ); + AesCcmSetKey(dec->aes, keys->client_write_key, specs->key_size); + XMEMCPY(keys->aead_dec_imp_IV, + keys->client_write_IV, AEAD_IMP_IV_SZ); } enc->setup = 1; dec->setup = 1; @@ -1210,7 +1273,7 @@ int StoreKeys(CYASSL* ssl, const byte* keyData) #ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead) { /* Initialize the AES-GCM explicit IV to a random number. */ - RNG_GenerateBlock(ssl->rng, ssl->keys.aead_exp_IV, AES_GCM_EXP_IV_SZ); + RNG_GenerateBlock(ssl->rng, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ); } #endif diff --git a/src/ssl.c b/src/ssl.c index b05a481af..2017d3533 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -5430,6 +5430,11 @@ int CyaSSL_set_compression(CYASSL* ssl) case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 : return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; + case TLS_RSA_WITH_AES_128_CCM_8_SHA256 : + return "TLS_RSA_WITH_AES_128_CCM_8_SHA256"; + case TLS_RSA_WITH_AES_256_CCM_8_SHA384 : + return "TLS_RSA_WITH_AES_256_CCM_8_SHA384"; + default: return "NONE"; } diff --git a/tests/include.am b/tests/include.am index 43d5c2c47..5b420fc42 100644 --- a/tests/include.am +++ b/tests/include.am @@ -27,6 +27,7 @@ EXTRA_DIST += tests/test.conf \ tests/test-aesgcm.conf \ tests/test-aesgcm-ecc.conf \ tests/test-aesgcm-openssl.conf \ + tests/test-aesccm.conf \ tests/test-dtls.conf \ tests/test-rabbit.conf \ tests/test-null.conf \ diff --git a/tests/suites.c b/tests/suites.c index 3bcb23e21..bc22cc865 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -370,6 +370,17 @@ int SuiteTest(void) } #endif +#if defined(HAVE_AESCCM) + /* add aesccm extra suites */ + strcpy(argv0[1], "tests/test-aesccm.conf"); + printf("starting aesccm extra cipher suite tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + exit(EXIT_FAILURE); + } +#endif + #ifdef CYASSL_DTLS /* add dtls extra suites */ strcpy(argv0[1], "tests/test-dtls.conf"); diff --git a/tests/test-aesccm.conf b/tests/test-aesccm.conf new file mode 100644 index 000000000..eba2a9ea7 --- /dev/null +++ b/tests/test-aesccm.conf @@ -0,0 +1,16 @@ +# server TLSv1.2 AES128-CCM-8-SHA256 +-v 3 +-l AES128-CCM-8-SHA256 + +# client TLSv1.2 AES128-CCM-8-SHA256 +-v 3 +-l AES128-CCM-8-SHA256 + +# server TLSv1.2 AES256-CCM-8-SHA384 +-v 3 +-l AES256-CCM-8-SHA384 + +# client TLSv1.2 AES256-CCM-8-SHA384 +-v 3 +-l AES256-CCM-8-SHA384 +