diff --git a/examples/client/client.c b/examples/client/client.c index 23bbbf176..b8238ba1d 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1024,6 +1024,34 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) ssl = wolfSSL_new(ctx); if (ssl == NULL) err_sys("unable to get SSL object"); + + #ifdef HAVE_SUPPORTED_CURVES /* add curves to supported curves extension */ + if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP256R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp256r1"); + } + if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP384R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp384r1"); + } + if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP521R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp521r1"); + } + if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP224R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp224r1"); + } + if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP192R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp192r1"); + } + if (wolfSSL_UseSupportedCurve(ssl, WOLFSSL_ECC_SECP160R1) + != SSL_SUCCESS) { + err_sys("unable to set curve secp160r1"); + } + #endif + #ifdef HAVE_SESSION_TICKET wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session"); #endif @@ -1071,16 +1099,6 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif tcp_connect(&sockfd, host, port, doDTLS, ssl); - -#ifdef HAVE_POLY1305 - /* use old poly to connect with google and wolfssl.com server */ - if (!XSTRNCMP(domain, "www.google.com", 14) || - !XSTRNCMP(domain, "www.wolfssl.com", 15)) { - if (wolfSSL_use_old_poly(ssl, 1) != 0) - err_sys("unable to set to old poly"); - } -#endif - wolfSSL_set_fd(ssl, sockfd); #ifdef HAVE_CRL if (disableCRL == 0) { diff --git a/src/internal.c b/src/internal.c index b3e3c7a92..ceb5c6cb5 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1263,6 +1263,28 @@ void InitSuites(Suites* suites, ProtocolVersion pv, word16 haveRSA, } #endif +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + if (tls1_2 && haveECDSAsig) { + suites->suites[idx++] = CHACHA_BYTE; + suites->suites[idx++] = + TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256; + } +#endif + +#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + if (tls1_2 && haveRSA) { + suites->suites[idx++] = CHACHA_BYTE; + suites->suites[idx++] = TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256; + } +#endif + +#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + if (tls1_2 && haveRSA) { + suites->suites[idx++] = CHACHA_BYTE; + suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256; + } +#endif + #ifdef BUILD_TLS_RSA_WITH_NULL_SHA if (tls && haveRSA) { suites->suites[idx++] = 0; @@ -2008,8 +2030,9 @@ void FreeArrays(WOLFSSL* ssl, int keep) if (ssl->arrays) { XFREE(ssl->arrays->pendingMsg, ssl->heap, DYNAMIC_TYPE_ARRAYS); ssl->arrays->pendingMsg = NULL; + ForceZero(ssl->arrays, sizeof(Arrays)); /* clear arrays struct */ } - XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_CERT); + XFREE(ssl->arrays, ssl->heap, DYNAMIC_TYPE_ARRAYS); ssl->arrays = NULL; } @@ -2031,6 +2054,9 @@ void SSL_ResourceFree(WOLFSSL* ssl) XFREE(ssl->hsHashes, ssl->heap, DYNAMIC_TYPE_HASHES); XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN); + /* clear keys struct after session */ + ForceZero(&(ssl->keys), sizeof(Keys)); + #ifndef NO_DH XFREE(ssl->buffers.serverDH_Priv.buffer, ssl->heap, DYNAMIC_TYPE_DH); XFREE(ssl->buffers.serverDH_Pub.buffer, ssl->heap, DYNAMIC_TYPE_DH); @@ -3726,6 +3752,23 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (requirement == REQUIRES_DHE) return 1; break; + + case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + break; + + case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + if (requirement == REQUIRES_ECC_DSA) + return 1; + break; + + case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + if (requirement == REQUIRES_RSA) + return 1; + if (requirement == REQUIRES_DHE) + return 1; + break; } } @@ -5992,72 +6035,13 @@ static INLINE word32 GetSEQIncrement(WOLFSSL* ssl, int verify) static INLINE void AeadIncrementExpIV(WOLFSSL* ssl) { int i; - for (i = AEAD_EXP_IV_SZ-1; i >= 0; i--) { + for (i = AEAD_MAX_EXP_SZ-1; i >= 0; i--) { if (++ssl->keys.aead_exp_IV[i]) return; } } #if defined(HAVE_POLY1305) && defined(HAVE_CHACHA) -/*more recent rfc's concatonate input for poly1305 differently*/ -static int Poly1305Tag(WOLFSSL* ssl, byte* additional, const byte* out, - byte* cipher, word16 sz, byte* tag) -{ - int ret = 0; - int paddingSz = 0; - int msglen = (sz - ssl->specs.aead_mac_size); - word32 keySz = 32; - int blockSz = 16; - byte padding[16]; - - if (msglen < 0) - return INPUT_CASE_ERROR; - - XMEMSET(padding, 0, sizeof(padding)); - - if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0) - return ret; - - /* additional input to poly1305 */ - if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional, blockSz)) != 0) - return ret; - - /* cipher input */ - if ((ret = wc_Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0) - return ret; - - /* handle padding for cipher input to make it 16 bytes long */ - if (msglen % 16 != 0) { - paddingSz = (16 - (sz - ssl->specs.aead_mac_size) % 16); - if (paddingSz < 0) - return INPUT_CASE_ERROR; - - if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, paddingSz)) - != 0) - return ret; - } - - /* add size of AD and size of cipher to poly input */ - XMEMSET(padding, 0, sizeof(padding)); - padding[0] = blockSz; - - /* 32 bit size of cipher to 64 bit endian */ - padding[8] = msglen & 0xff; - padding[9] = (msglen >> 8) & 0xff; - padding[10] = (msglen >>16) & 0xff; - padding[11] = (msglen >>24) & 0xff; - if ((ret = wc_Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding))) - != 0) - return ret; - - /* generate tag */ - if ((ret = wc_Poly1305Final(ssl->auth.poly1305, tag)) != 0) - return ret; - - return ret; -} - - /* Used for the older version of creating AEAD tags with Poly1305 */ static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, const byte* out, byte* cipher, word16 sz, byte* tag) @@ -6077,9 +6061,6 @@ static int Poly1305TagOld(WOLFSSL* ssl, byte* additional, const byte* out, if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0) return ret; - /* add TLS compressed length and additional input to poly1305 */ - additional[AEAD_AUTH_DATA_SZ - 2] = (msglen >> 8) & 0xff; - additional[AEAD_AUTH_DATA_SZ - 1] = msglen & 0xff; if ((ret = wc_Poly1305Update(ssl->auth.poly1305, additional, AEAD_AUTH_DATA_SZ)) != 0) return ret; @@ -6118,42 +6099,48 @@ static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) { const byte* additionalSrc = input - RECORD_HEADER_SZ; - int ret = 0; + int ret = 0; + word32 msgLen = (sz - ssl->specs.aead_mac_size); byte tag[POLY1305_AUTH_SZ]; - byte additional[CHACHA20_BLOCK_SIZE]; - byte nonce[AEAD_NONCE_SZ]; - byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */ + byte add[AEAD_AUTH_DATA_SZ]; + byte nonce[CHACHA20_NONCE_SZ]; + byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for poly1305 */ #ifdef CHACHA_AEAD_TEST int i; #endif - XMEMSET(tag, 0, sizeof(tag)); - XMEMSET(nonce, 0, AEAD_NONCE_SZ); - XMEMSET(cipher, 0, sizeof(cipher)); - XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE); + XMEMSET(tag, 0, sizeof(tag)); + XMEMSET(nonce, 0, sizeof(nonce)); + XMEMSET(poly, 0, sizeof(poly)); + XMEMSET(add, 0, sizeof(add)); - /* get nonce */ - c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ - + AEAD_SEQ_OFFSET); + if (ssl->options.oldPoly != 0) { + /* get nonce */ + c32toa(ssl->keys.sequence_number, nonce + CHACHA20_OLD_OFFSET); + } /* opaque SEQ number stored for AD */ - c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET); + c32toa(GetSEQIncrement(ssl, 0), add + AEAD_SEQ_OFFSET); /* Store the type, version. Unfortunately, they are in * the input buffer ahead of the plaintext. */ #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - c16toa(ssl->keys.dtls_epoch, additional); + c16toa(ssl->keys.dtls_epoch, add); additionalSrc -= DTLS_HANDSHAKE_EXTRA; } #endif - XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3); + /* add TLS message size to additional data */ + add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff; + add[AEAD_AUTH_DATA_SZ - 1] = msgLen & 0xff; + + XMEMCPY(add + AEAD_TYPE_OFFSET, additionalSrc, 3); #ifdef CHACHA_AEAD_TEST printf("Encrypt Additional : "); - for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) { - printf("%02x", additional[i]); + for (i = 0; i < AEAD_AUTH_DATA_SZ; i++) { + printf("%02x", add[i]); } printf("\n\n"); printf("input before encryption :\n"); @@ -6165,36 +6152,65 @@ static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, printf("\n"); #endif - /* set the nonce for chacha and get poly1305 key */ - if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0) - return ret; + if (ssl->options.oldPoly == 0) { + /* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte + * record sequence number XORed with client_write_IV/server_write_IV */ + XMEMCPY(nonce, ssl->keys.aead_enc_imp_IV, CHACHA20_IMP_IV_SZ); + nonce[4] ^= add[0]; + nonce[5] ^= add[1]; + nonce[6] ^= add[2]; + nonce[7] ^= add[3]; + nonce[8] ^= add[4]; + nonce[9] ^= add[5]; + nonce[10] ^= add[6]; + nonce[11] ^= add[7]; + } - if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, cipher, - cipher, sizeof(cipher))) != 0) + /* set the nonce for chacha and get poly1305 key */ + if ((ret = wc_Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0) { + ForceZero(nonce, CHACHA20_NONCE_SZ); + return ret; + } + + ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */ + /* create Poly1305 key using chacha20 keystream */ + if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, poly, + poly, sizeof(poly))) != 0) return ret; /* encrypt the plain text */ - if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out, input, - sz - ssl->specs.aead_mac_size)) != 0) + if ((ret = wc_Chacha_Process(ssl->encrypt.chacha, out, + input, msgLen)) != 0) { + ForceZero(poly, sizeof(poly)); return ret; + } - /* get the tag : future use of hmac could go here*/ - if (ssl->options.oldPoly == 1) { - if ((ret = Poly1305TagOld(ssl, additional, (const byte* )out, - cipher, sz, tag)) != 0) + /* get the poly1305 tag using either old padding scheme or more recent */ + if (ssl->options.oldPoly != 0) { + if ((ret = Poly1305TagOld(ssl, add, (const byte* )out, + poly, sz, tag)) != 0) { + ForceZero(poly, sizeof(poly)); return ret; + } } else { - if ((ret = Poly1305Tag(ssl, additional, (const byte* )out, - cipher, sz, tag)) != 0) + if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, + sizeof(poly))) != 0) { + ForceZero(poly, sizeof(poly)); return ret; + } + if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add, + sizeof(add), out, msgLen, tag, sizeof(tag))) != 0) { + ForceZero(poly, sizeof(poly)); + return ret; + } } + ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */ /* append tag to ciphertext */ - XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag)); + XMEMCPY(out + msgLen, tag, sizeof(tag)); AeadIncrementExpIV(ssl); - ForceZero(nonce, AEAD_NONCE_SZ); #ifdef CHACHA_AEAD_TEST printf("mac tag :\n"); @@ -6219,16 +6235,12 @@ static int ChachaAEADEncrypt(WOLFSSL* ssl, byte* out, const byte* input, static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, word16 sz) { - byte additional[CHACHA20_BLOCK_SIZE]; - byte nonce[AEAD_NONCE_SZ]; + byte add[AEAD_AUTH_DATA_SZ]; + byte nonce[CHACHA20_NONCE_SZ]; byte tag[POLY1305_AUTH_SZ]; - byte cipher[CHACHA20_256_KEY_SIZE]; /* generated key for mac */ - int ret = 0; - - XMEMSET(tag, 0, sizeof(tag)); - XMEMSET(cipher, 0, sizeof(cipher)); - XMEMSET(nonce, 0, AEAD_NONCE_SZ); - XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE); + byte poly[CHACHA20_256_KEY_SIZE]; /* generated key for mac */ + int ret = 0; + int msgLen = (sz - ssl->specs.aead_mac_size); #ifdef CHACHA_AEAD_TEST int i; @@ -6241,64 +6253,99 @@ static int ChachaAEADDecrypt(WOLFSSL* ssl, byte* plain, const byte* input, printf("\n"); #endif - /* get nonce */ - c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ - + AEAD_SEQ_OFFSET); + XMEMSET(tag, 0, sizeof(tag)); + XMEMSET(poly, 0, sizeof(poly)); + XMEMSET(nonce, 0, sizeof(nonce)); + XMEMSET(add, 0, sizeof(add)); + + if (ssl->options.oldPoly != 0) { + /* get nonce */ + c32toa(ssl->keys.peer_sequence_number, nonce + CHACHA20_OLD_OFFSET); + } /* sequence number field is 64-bits, we only use 32-bits */ - c32toa(GetSEQIncrement(ssl, 1), additional + AEAD_SEQ_OFFSET); + c32toa(GetSEQIncrement(ssl, 1), add + AEAD_SEQ_OFFSET); /* get AD info */ - additional[AEAD_TYPE_OFFSET] = ssl->curRL.type; - additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; - additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; + add[AEAD_TYPE_OFFSET] = ssl->curRL.type; + add[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; + add[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; /* Store the type, version. */ #ifdef WOLFSSL_DTLS if (ssl->options.dtls) - c16toa(ssl->keys.dtls_state.curEpoch, additional); + c16toa(ssl->keys.dtls_state.curEpoch, add); #endif + /* add TLS message size to additional data */ + add[AEAD_AUTH_DATA_SZ - 2] = (msgLen >> 8) & 0xff; + add[AEAD_AUTH_DATA_SZ - 1] = msgLen & 0xff; + #ifdef CHACHA_AEAD_TEST printf("Decrypt Additional : "); - for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) { - printf("%02x", additional[i]); + for (i = 0; i < AEAD_AUTH_DATA_SZ; i++) { + printf("%02x", add[i]); } printf("\n\n"); #endif + if (ssl->options.oldPoly == 0) { + /* nonce is formed by 4 0x00 byte padded to the left followed by 8 byte + * record sequence number XORed with client_write_IV/server_write_IV */ + XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, CHACHA20_IMP_IV_SZ); + nonce[4] ^= add[0]; + nonce[5] ^= add[1]; + nonce[6] ^= add[2]; + nonce[7] ^= add[3]; + nonce[8] ^= add[4]; + nonce[9] ^= add[5]; + nonce[10] ^= add[6]; + nonce[11] ^= add[7]; + } + /* set nonce and get poly1305 key */ - if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0) + if ((ret = wc_Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0) { + ForceZero(nonce, CHACHA20_NONCE_SZ); + return ret; + } + + ForceZero(nonce, CHACHA20_NONCE_SZ); /* done with nonce, clear it */ + /* use chacha20 keystream to get poly1305 key for tag */ + if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, poly, + poly, sizeof(poly))) != 0) return ret; - if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, cipher, - cipher, sizeof(cipher))) != 0) - return ret; - - /* get the tag : future use of hmac could go here*/ - if (ssl->options.oldPoly == 1) { - if ((ret = Poly1305TagOld(ssl, additional, input, cipher, - sz, tag)) != 0) + /* get the tag using Poly1305 */ + if (ssl->options.oldPoly != 0) { + if ((ret = Poly1305TagOld(ssl, add, input, poly, sz, tag)) != 0) { + ForceZero(poly, sizeof(poly)); return ret; + } } else { - if ((ret = Poly1305Tag(ssl, additional, input, cipher, - sz, tag)) != 0) + if ((ret = wc_Poly1305SetKey(ssl->auth.poly1305, poly, + sizeof(poly))) != 0) { + ForceZero(poly, sizeof(poly)); return ret; + } + if ((ret = wc_Poly1305_MAC(ssl->auth.poly1305, add, + sizeof(add), (byte*)input, msgLen, tag, sizeof(tag))) != 0) { + ForceZero(poly, sizeof(poly)); + return ret; + } } + ForceZero(poly, sizeof(poly)); /* done with poly1305 key, clear it */ - /* check mac sent along with packet */ - if (ConstantCompare(input + sz - ssl->specs.aead_mac_size, tag, - ssl->specs.aead_mac_size) != 0) { - WOLFSSL_MSG("Mac did not match"); + /* check tag sent along with packet */ + if (ConstantCompare(input + msgLen, tag, ssl->specs.aead_mac_size) != 0) { + WOLFSSL_MSG("MAC did not match"); SendAlert(ssl, alert_fatal, bad_record_mac); - ForceZero(nonce, AEAD_NONCE_SZ); return VERIFY_MAC_ERROR; } - /* if mac was good decrypt message */ - if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, plain, input, - sz - ssl->specs.aead_mac_size)) != 0) + /* if the tag was good decrypt message */ + if ((ret = wc_Chacha_Process(ssl->decrypt.chacha, plain, + input, msgLen)) != 0) return ret; #ifdef CHACHA_AEAD_TEST @@ -6358,7 +6405,7 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) case wolfssl_aes_gcm: { byte additional[AEAD_AUTH_DATA_SZ]; - byte nonce[AEAD_NONCE_SZ]; + byte nonce[AESGCM_NONCE_SZ]; const byte* additionalSrc = input - 5; XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); @@ -6379,30 +6426,31 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) /* Store the length of the plain text minus the explicit * IV length minus the authentication tag size. */ - c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, + c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, 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); + ssl->keys.aead_enc_imp_IV, AESGCM_IMP_IV_SZ); + XMEMCPY(nonce + AESGCM_IMP_IV_SZ, + ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ); ret = wc_AesGcmEncrypt(ssl->encrypt.aes, - out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ, - sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, - nonce, AEAD_NONCE_SZ, + out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ, + sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + nonce, AESGCM_NONCE_SZ, out + sz - ssl->specs.aead_mac_size, ssl->specs.aead_mac_size, additional, AEAD_AUTH_DATA_SZ); AeadIncrementExpIV(ssl); - ForceZero(nonce, AEAD_NONCE_SZ); + ForceZero(nonce, AESGCM_NONCE_SZ); } break; #endif #ifdef HAVE_AESCCM + /* AEAD CCM uses same size as macros for AESGCM */ case wolfssl_aes_ccm: { byte additional[AEAD_AUTH_DATA_SZ]; - byte nonce[AEAD_NONCE_SZ]; + byte nonce[AESGCM_NONCE_SZ]; const byte* additionalSrc = input - 5; XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); @@ -6423,21 +6471,21 @@ static INLINE int Encrypt(WOLFSSL* ssl, byte* out, const byte* input, word16 sz) /* Store the length of the plain text minus the explicit * IV length minus the authentication tag size. */ - c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, + c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, 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); + ssl->keys.aead_enc_imp_IV, AESGCM_IMP_IV_SZ); + XMEMCPY(nonce + AESGCM_IMP_IV_SZ, + ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ); ret = wc_AesCcmEncrypt(ssl->encrypt.aes, - out + AEAD_EXP_IV_SZ, input + AEAD_EXP_IV_SZ, - sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, - nonce, AEAD_NONCE_SZ, + out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ, + sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + nonce, AESGCM_NONCE_SZ, out + sz - ssl->specs.aead_mac_size, ssl->specs.aead_mac_size, additional, AEAD_AUTH_DATA_SZ); AeadIncrementExpIV(ssl); - ForceZero(nonce, AEAD_NONCE_SZ); + ForceZero(nonce, AESGCM_NONCE_SZ); } break; #endif @@ -6527,7 +6575,7 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, case wolfssl_aes_gcm: { byte additional[AEAD_AUTH_DATA_SZ]; - byte nonce[AEAD_NONCE_SZ]; + byte nonce[AESGCM_NONCE_SZ]; XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); @@ -6543,31 +6591,32 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; - c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, + c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, 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); + XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AESGCM_IMP_IV_SZ); + XMEMCPY(nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ); if (wc_AesGcmDecrypt(ssl->decrypt.aes, - plain + AEAD_EXP_IV_SZ, - input + AEAD_EXP_IV_SZ, - sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, - nonce, AEAD_NONCE_SZ, + plain + AESGCM_EXP_IV_SZ, + input + AESGCM_EXP_IV_SZ, + sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + nonce, AESGCM_NONCE_SZ, input + sz - ssl->specs.aead_mac_size, ssl->specs.aead_mac_size, additional, AEAD_AUTH_DATA_SZ) < 0) { SendAlert(ssl, alert_fatal, bad_record_mac); ret = VERIFY_MAC_ERROR; } - ForceZero(nonce, AEAD_NONCE_SZ); + ForceZero(nonce, AESGCM_NONCE_SZ); } break; #endif #ifdef HAVE_AESCCM + /* AESGCM AEAD macros use same size as AESCCM */ case wolfssl_aes_ccm: { byte additional[AEAD_AUTH_DATA_SZ]; - byte nonce[AEAD_NONCE_SZ]; + byte nonce[AESGCM_NONCE_SZ]; XMEMSET(additional, 0, AEAD_AUTH_DATA_SZ); @@ -6583,22 +6632,22 @@ static INLINE int Decrypt(WOLFSSL* ssl, byte* plain, const byte* input, additional[AEAD_VMAJ_OFFSET] = ssl->curRL.pvMajor; additional[AEAD_VMIN_OFFSET] = ssl->curRL.pvMinor; - c16toa(sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, + c16toa(sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, 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); + XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AESGCM_IMP_IV_SZ); + XMEMCPY(nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ); if (wc_AesCcmDecrypt(ssl->decrypt.aes, - plain + AEAD_EXP_IV_SZ, - input + AEAD_EXP_IV_SZ, - sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, - nonce, AEAD_NONCE_SZ, + plain + AESGCM_EXP_IV_SZ, + input + AESGCM_EXP_IV_SZ, + sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + nonce, AESGCM_NONCE_SZ, input + sz - ssl->specs.aead_mac_size, ssl->specs.aead_mac_size, additional, AEAD_AUTH_DATA_SZ) < 0) { SendAlert(ssl, alert_fatal, bad_record_mac); ret = VERIFY_MAC_ERROR; } - ForceZero(nonce, AEAD_NONCE_SZ); + ForceZero(nonce, AESGCM_NONCE_SZ); } break; #endif @@ -6677,7 +6726,7 @@ static int SanityCheckCipherText(WOLFSSL* ssl, word32 encryptSz) else if (ssl->specs.cipher_type == aead) { minLength = ssl->specs.aead_mac_size; /* authTag size */ if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) - minLength += AEAD_EXP_IV_SZ; /* explicit IV */ + minLength += AESGCM_EXP_IV_SZ; /* explicit IV */ } if (encryptSz < minLength) { @@ -6963,7 +7012,7 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx) } else if (ssl->specs.cipher_type == aead) { if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) - ivExtra = AEAD_EXP_IV_SZ; + ivExtra = AESGCM_EXP_IV_SZ; } dataSz = msgSz - ivExtra - ssl->keys.padSz; @@ -7365,7 +7414,7 @@ int ProcessReply(WOLFSSL* ssl) /* go past TLSv1.1 IV */ if (ssl->specs.cipher_type == aead && ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) - ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ; + ssl->buffers.inputBuffer.idx += AESGCM_EXP_IV_SZ; #endif /* ATOMIC_USER */ } else { @@ -7384,7 +7433,7 @@ int ProcessReply(WOLFSSL* ssl) /* go past TLSv1.1 IV */ if (ssl->specs.cipher_type == aead && ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) - ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ; + ssl->buffers.inputBuffer.idx += AESGCM_EXP_IV_SZ; ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx, @@ -7914,10 +7963,10 @@ static int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, #ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead) { if (ssl->specs.bulk_cipher_algorithm != wolfssl_chacha) - ivSz = AEAD_EXP_IV_SZ; + ivSz = AESGCM_EXP_IV_SZ; sz += (ivSz + ssl->specs.aead_mac_size - digestSz); - XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ); + XMEMCPY(iv, ssl->keys.aead_exp_IV, AESGCM_EXP_IV_SZ); } #endif if (sz > (word32)outSz) { @@ -9837,6 +9886,18 @@ static const char* const cipher_names[] = "DHE-RSA-CHACHA20-POLY1305", #endif +#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + "ECDHE-RSA-CHACHA20-POLY1305-OLD", +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + "ECDHE-ECDSA-CHACHA20-POLY1305-OLD", +#endif + +#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + "DHE-RSA-CHACHA20-POLY1305-OLD", +#endif + #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA "ADH-AES128-SHA", #endif @@ -10239,6 +10300,18 @@ static int cipher_name_idx[] = TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, #endif +#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256, +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256, +#endif + +#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256, +#endif + #ifdef BUILD_TLS_DH_anon_WITH_AES_128_CBC_SHA TLS_DH_anon_WITH_AES_128_CBC_SHA, #endif diff --git a/src/keys.c b/src/keys.c index 3545a5e1c..27d7ac598 100644 --- a/src/keys.c +++ b/src/keys.c @@ -60,6 +60,62 @@ int SetCipherSpecs(WOLFSSL* ssl) if (ssl->options.cipherSuite0 == CHACHA_BYTE) { switch (ssl->options.cipherSuite) { +#ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256: + ssl->specs.bulk_cipher_algorithm = wolfssl_chacha; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = ecc_diffie_hellman_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 = CHACHA20_256_KEY_SIZE; + ssl->specs.block_size = CHACHA20_BLOCK_SIZE; + ssl->specs.iv_size = CHACHA20_IV_SIZE; + ssl->specs.aead_mac_size = POLY1305_AUTH_SZ; + ssl->options.oldPoly = 1; /* use old poly1305 padding */ + + break; +#endif + +#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256: + ssl->specs.bulk_cipher_algorithm = wolfssl_chacha; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = ecc_diffie_hellman_kea; + ssl->specs.sig_algo = ecc_dsa_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = CHACHA20_256_KEY_SIZE; + ssl->specs.block_size = CHACHA20_BLOCK_SIZE; + ssl->specs.iv_size = CHACHA20_IV_SIZE; + ssl->specs.aead_mac_size = POLY1305_AUTH_SZ; + ssl->options.oldPoly = 1; /* use old poly1305 padding */ + + break; +#endif + +#ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256: + ssl->specs.bulk_cipher_algorithm = wolfssl_chacha; + ssl->specs.cipher_type = aead; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = diffie_hellman_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 = CHACHA20_256_KEY_SIZE; + ssl->specs.block_size = CHACHA20_BLOCK_SIZE; + ssl->specs.iv_size = CHACHA20_IV_SIZE; + ssl->specs.aead_mac_size = POLY1305_AUTH_SZ; + ssl->options.oldPoly = 1; /* use old poly1305 padding */ + + break; +#endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: ssl->specs.bulk_cipher_algorithm = wolfssl_chacha; @@ -74,6 +130,7 @@ int SetCipherSpecs(WOLFSSL* ssl) ssl->specs.block_size = CHACHA20_BLOCK_SIZE; ssl->specs.iv_size = CHACHA20_IV_SIZE; ssl->specs.aead_mac_size = POLY1305_AUTH_SZ; + ssl->options.oldPoly = 0; /* use recent padding RFC */ break; #endif @@ -92,6 +149,7 @@ int SetCipherSpecs(WOLFSSL* ssl) ssl->specs.block_size = CHACHA20_BLOCK_SIZE; ssl->specs.iv_size = CHACHA20_IV_SIZE; ssl->specs.aead_mac_size = POLY1305_AUTH_SZ; + ssl->options.oldPoly = 0; /* use recent padding RFC */ break; #endif @@ -110,6 +168,7 @@ int SetCipherSpecs(WOLFSSL* ssl) ssl->specs.block_size = CHACHA20_BLOCK_SIZE; ssl->specs.iv_size = CHACHA20_IV_SIZE; ssl->specs.aead_mac_size = POLY1305_AUTH_SZ; + ssl->options.oldPoly = 0; /* use recent padding RFC */ break; #endif @@ -538,7 +597,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -556,7 +615,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -574,7 +633,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -592,7 +651,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -610,7 +669,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -628,7 +687,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -646,7 +705,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -664,7 +723,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -682,7 +741,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_8_AUTH_SZ; break; @@ -700,7 +759,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_8_AUTH_SZ; break; @@ -719,7 +778,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_8_AUTH_SZ; break; @@ -737,7 +796,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_8_AUTH_SZ; break; @@ -755,7 +814,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_8_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -774,7 +833,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_8_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -793,7 +852,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_16_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -812,7 +871,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_16_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -831,7 +890,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_16_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -850,7 +909,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_CCM_16_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -1099,7 +1158,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -1118,7 +1177,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -1137,7 +1196,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -1156,7 +1215,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; ssl->options.usingPSK_cipher = 1; @@ -1543,7 +1602,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -1561,7 +1620,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -1579,7 +1638,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -1597,7 +1656,7 @@ int SetCipherSpecs(WOLFSSL* 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 = AEAD_IMP_IV_SZ; + ssl->specs.iv_size = AESGCM_IMP_IV_SZ; ssl->specs.aead_mac_size = AES_GCM_AUTH_SZ; break; @@ -1899,6 +1958,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + /* Check that the max implicit iv size is suffecient */ + #if (AEAD_MAX_IMP_SZ < 12) /* CHACHA20_IMP_IV_SZ */ + #error AEAD_MAX_IMP_SZ is too small for ChaCha20 + #endif + #if (MAX_WRITE_IV_SZ < 12) /* CHACHA20_IMP_IV_SZ */ + #error MAX_WRITE_IV_SZ is too small for ChaCha20 + #endif + if (specs->bulk_cipher_algorithm == wolfssl_chacha) { int chachaRet; if (enc && enc->chacha == NULL) @@ -1916,14 +1983,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, chachaRet = wc_Chacha_SetKey(enc->chacha, keys->client_write_key, specs->key_size); XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV, - AEAD_IMP_IV_SZ); + CHACHA20_IMP_IV_SZ); if (chachaRet != 0) return chachaRet; } if (dec) { chachaRet = wc_Chacha_SetKey(dec->chacha, keys->server_write_key, specs->key_size); XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV, - AEAD_IMP_IV_SZ); + CHACHA20_IMP_IV_SZ); if (chachaRet != 0) return chachaRet; } } @@ -1932,14 +1999,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, chachaRet = wc_Chacha_SetKey(enc->chacha, keys->server_write_key, specs->key_size); XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV, - AEAD_IMP_IV_SZ); + CHACHA20_IMP_IV_SZ); if (chachaRet != 0) return chachaRet; } if (dec) { chachaRet = wc_Chacha_SetKey(dec->chacha, keys->client_write_key, specs->key_size); XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV, - AEAD_IMP_IV_SZ); + CHACHA20_IMP_IV_SZ); if (chachaRet != 0) return chachaRet; } } @@ -1952,6 +2019,11 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #endif #ifdef HAVE_HC128 + /* check that buffer sizes are sufficient */ + #if (MAX_WRITE_IV_SZ < 16) /* HC_128_IV_SIZE */ + #error MAX_WRITE_IV_SZ too small for HC128 + #endif + if (specs->bulk_cipher_algorithm == wolfssl_hc128) { int hcRet; if (enc && enc->hc128 == NULL) @@ -1996,6 +2068,11 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #endif #ifdef BUILD_RABBIT + /* check that buffer sizes are sufficient */ + #if (MAX_WRITE_IV_SZ < 8) /* RABBIT_IV_SIZE */ + #error MAX_WRITE_IV_SZ too small for RABBIT + #endif + if (specs->bulk_cipher_algorithm == wolfssl_rabbit) { int rabRet; if (enc && enc->rabbit == NULL) @@ -2040,6 +2117,11 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #endif #ifdef BUILD_DES3 + /* check that buffer sizes are sufficient */ + #if (MAX_WRITE_IV_SZ < 8) /* DES_IV_SIZE */ + #error MAX_WRITE_IV_SZ too small for 3DES + #endif + if (specs->bulk_cipher_algorithm == wolfssl_triple_des) { int desRet = 0; @@ -2099,6 +2181,11 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #endif #ifdef BUILD_AES + /* check that buffer sizes are sufficient */ + #if (MAX_WRITE_IV_SZ < 16) /* AES_IV_SIZE */ + #error MAX_WRITE_IV_SZ too small for AES + #endif + if (specs->bulk_cipher_algorithm == wolfssl_aes) { int aesRet = 0; @@ -2162,6 +2249,17 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #endif #ifdef BUILD_AESGCM + /* check that buffer sizes are sufficient */ + #if (AEAD_MAX_IMP_SZ < 4) /* AESGCM_IMP_IV_SZ */ + #error AEAD_MAX_IMP_SZ too small for AESGCM + #endif + #if (AEAD_MAX_EXP_SZ < 8) /* AESGCM_EXP_IV_SZ */ + #error AEAD_MAX_EXP_SZ too small for AESGCM + #endif + #if (MAX_WRITE_IV_SZ < 4) /* AESGCM_IMP_IV_SZ */ + #error MAX_WRITE_IV_SZ too small for AESGCM + #endif + if (specs->bulk_cipher_algorithm == wolfssl_aes_gcm) { int gcmRet; @@ -2180,14 +2278,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, specs->key_size); if (gcmRet != 0) return gcmRet; XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV, - AEAD_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); } if (dec) { gcmRet = wc_AesGcmSetKey(dec->aes, keys->server_write_key, specs->key_size); if (gcmRet != 0) return gcmRet; XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV, - AEAD_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); } } else { @@ -2196,14 +2294,14 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, specs->key_size); if (gcmRet != 0) return gcmRet; XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV, - AEAD_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); } if (dec) { gcmRet = wc_AesGcmSetKey(dec->aes, keys->client_write_key, specs->key_size); if (gcmRet != 0) return gcmRet; XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV, - AEAD_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); } } if (enc) @@ -2214,6 +2312,17 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #endif #ifdef HAVE_AESCCM + /* check that buffer sizes are sufficient (CCM is same size as GCM) */ + #if (AEAD_MAX_IMP_SZ < 4) /* AESGCM_IMP_IV_SZ */ + #error AEAD_MAX_IMP_SZ too small for AESCCM + #endif + #if (AEAD_MAX_EXP_SZ < 8) /* AESGCM_EXP_IV_SZ */ + #error AEAD_MAX_EXP_SZ too small for AESCCM + #endif + #if (MAX_WRITE_IV_SZ < 4) /* AESGCM_IMP_IV_SZ */ + #error MAX_WRITE_IV_SZ too small for AESCCM + #endif + if (specs->bulk_cipher_algorithm == wolfssl_aes_ccm) { if (enc && enc->aes == NULL) enc->aes = (Aes*)XMALLOC(sizeof(Aes), heap, DYNAMIC_TYPE_CIPHER); @@ -2228,24 +2337,24 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, if (enc) { wc_AesCcmSetKey(enc->aes, keys->client_write_key, specs->key_size); XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV, - AEAD_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); } if (dec) { wc_AesCcmSetKey(dec->aes, keys->server_write_key, specs->key_size); XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV, - AEAD_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); } } else { if (enc) { wc_AesCcmSetKey(enc->aes, keys->server_write_key, specs->key_size); XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV, - AEAD_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); } if (dec) { wc_AesCcmSetKey(dec->aes, keys->client_write_key, specs->key_size); XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV, - AEAD_IMP_IV_SZ); + AESGCM_IMP_IV_SZ); } } if (enc) @@ -2256,6 +2365,11 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #endif #ifdef HAVE_CAMELLIA + /* check that buffer sizes are sufficient */ + #if (MAX_WRITE_IV_SZ < 16) /* CAMELLIA_IV_SIZE */ + #error MAX_WRITE_IV_SZ too small for CAMELLIA + #endif + if (specs->bulk_cipher_algorithm == wolfssl_camellia) { int camRet; @@ -2303,6 +2417,11 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, #endif #ifdef HAVE_IDEA + /* check that buffer sizes are sufficient */ + #if (MAX_WRITE_IV_SZ < 8) /* IDEA_IV_SIZE */ + #error MAX_WRITE_IV_SZ too small for IDEA + #endif + if (specs->bulk_cipher_algorithm == wolfssl_idea) { int ideaRet; @@ -2469,14 +2588,14 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) XMEMCPY(ssl->keys.client_write_key, keys->client_write_key, AES_256_KEY_SIZE); XMEMCPY(ssl->keys.client_write_IV, - keys->client_write_IV, AES_IV_SIZE); + keys->client_write_IV, MAX_WRITE_IV_SZ); } else { XMEMCPY(ssl->keys.server_write_MAC_secret, keys->server_write_MAC_secret, MAX_DIGEST_SIZE); XMEMCPY(ssl->keys.server_write_key, keys->server_write_key, AES_256_KEY_SIZE); XMEMCPY(ssl->keys.server_write_IV, - keys->server_write_IV, AES_IV_SIZE); + keys->server_write_IV, MAX_WRITE_IV_SZ); } if (wc_encrypt) { ssl->keys.sequence_number = keys->sequence_number; @@ -2484,15 +2603,15 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) if (ssl->specs.cipher_type == aead) { /* Initialize the AES-GCM/CCM explicit IV to a zero. */ XMEMCPY(ssl->keys.aead_exp_IV, keys->aead_exp_IV, - AEAD_EXP_IV_SZ); + AEAD_MAX_EXP_SZ); /* Initialize encrypt implicit IV by encrypt side */ if (ssl->options.side == WOLFSSL_CLIENT_END) { XMEMCPY(ssl->keys.aead_enc_imp_IV, - keys->client_write_IV, AEAD_IMP_IV_SZ); + keys->client_write_IV, AEAD_MAX_IMP_SZ); } else { XMEMCPY(ssl->keys.aead_enc_imp_IV, - keys->server_write_IV, AEAD_IMP_IV_SZ); + keys->server_write_IV, AEAD_MAX_IMP_SZ); } } #endif @@ -2504,10 +2623,10 @@ int SetKeysSide(WOLFSSL* ssl, enum encrypt_side side) /* Initialize decrypt implicit IV by decrypt side */ if (ssl->options.side == WOLFSSL_SERVER_END) { XMEMCPY(ssl->keys.aead_dec_imp_IV, - keys->client_write_IV, AEAD_IMP_IV_SZ); + keys->client_write_IV, AEAD_MAX_IMP_SZ); } else { XMEMCPY(ssl->keys.aead_dec_imp_IV, - keys->server_write_IV, AEAD_IMP_IV_SZ); + keys->server_write_IV, AEAD_MAX_IMP_SZ); } } #endif @@ -2555,7 +2674,7 @@ int StoreKeys(WOLFSSL* ssl, const byte* keyData) #ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead) { /* Initialize the AES-GCM/CCM explicit IV to a zero. */ - XMEMSET(keys->aead_exp_IV, 0, AEAD_EXP_IV_SZ); + XMEMSET(keys->aead_exp_IV, 0, AEAD_MAX_EXP_SZ); } #endif diff --git a/src/sniffer.c b/src/sniffer.c index 3ab4fd96c..86fc136dc 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -1973,23 +1973,23 @@ static int Decrypt(SSL* ssl, byte* output, const byte* input, word32 sz) #ifdef HAVE_AESGCM case wolfssl_aes_gcm: - if (sz >= (word32)(AEAD_EXP_IV_SZ + ssl->specs.aead_mac_size)) + if (sz >= (word32)(AESGCM_EXP_IV_SZ + ssl->specs.aead_mac_size)) { - byte nonce[AEAD_NONCE_SZ]; - XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ); - XMEMCPY(nonce + AEAD_IMP_IV_SZ, input, AEAD_EXP_IV_SZ); + byte nonce[AESGCM_NONCE_SZ]; + XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AESGCM_IMP_IV_SZ); + XMEMCPY(nonce + AESGCM_IMP_IV_SZ, input, AESGCM_EXP_IV_SZ); if (wc_AesGcmEncrypt(ssl->decrypt.aes, output, - input + AEAD_EXP_IV_SZ, - sz - AEAD_EXP_IV_SZ - ssl->specs.aead_mac_size, - nonce, AEAD_NONCE_SZ, + input + AESGCM_EXP_IV_SZ, + sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + nonce, AESGCM_NONCE_SZ, NULL, 0, NULL, 0) < 0) { Trace(BAD_DECRYPT); ret = -1; } - ForceZero(nonce, AEAD_NONCE_SZ); + ForceZero(nonce, AESGCM_NONCE_SZ); } else { Trace(BAD_DECRYPT_SIZE); diff --git a/src/ssl.c b/src/ssl.c index ed989932f..a83923c84 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -235,6 +235,8 @@ void wolfSSL_free(WOLFSSL* ssl) int wolfSSL_use_old_poly(WOLFSSL* ssl, int value) { WOLFSSL_ENTER("SSL_use_old_poly"); + WOLFSSL_MSG("Warning SSL connection auto detects old/new and this function" + "is depriciated"); ssl->options.oldPoly = value; WOLFSSL_LEAVE("SSL_use_old_poly", 0); return 0; @@ -423,7 +425,7 @@ int wolfSSL_GetObjectSize(void) printf(" sizeof rabbit = %lu\n", sizeof(Rabbit)); #endif #ifdef HAVE_CHACHA - printf(" sizeof chacha = %lu\n", sizeof(Chacha)); + printf(" sizeof chacha = %lu\n", sizeof(ChaCha)); #endif printf("sizeof cipher specs = %lu\n", sizeof(CipherSpecs)); printf("sizeof keys = %lu\n", sizeof(Keys)); @@ -10169,16 +10171,25 @@ const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher) if (cipher->ssl->options.cipherSuite0 == CHACHA_BYTE) { /* ChaCha suites */ switch (cipher->ssl->options.cipherSuite) { -#ifdef HAVE_CHACHA +#ifdef HAVE_POLY1305 #ifndef NO_RSA case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : return "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"; case TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : return "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"; + + case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + return "TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256"; + + case TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + return "TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256"; #endif case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 : return "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"; + + case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + return "TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256"; #endif } } diff --git a/src/tls.c b/src/tls.c index 793b55c33..77437a8c6 100644 --- a/src/tls.c +++ b/src/tls.c @@ -2657,7 +2657,8 @@ static void TLSX_EllipticCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore) int i; for (i = 0; i < ssl->suites->suiteSz; i+= 2) - if (ssl->suites->suites[i] == ECC_BYTE) + if (ssl->suites->suites[i] == ECC_BYTE || + ssl->suites->suites[i] == CHACHA_BYTE) return; /* turns semaphore on to avoid sending this extension. */ @@ -2734,7 +2735,7 @@ static int TLSX_EllipticCurve_Parse(WOLFSSL* ssl, byte* input, word16 length, } int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { - TLSX* extension = (first == ECC_BYTE) + TLSX* extension = (first == ECC_BYTE || first == CHACHA_BYTE) ? TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS) : NULL; EllipticCurve* curve = NULL; @@ -2773,6 +2774,7 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { default: continue; /* unsupported curve */ } + if (first == ECC_BYTE) { switch (second) { #ifndef NO_DSA /* ECDHE_ECDSA */ @@ -2835,6 +2837,33 @@ int TLSX_ValidateEllipticCurves(WOLFSSL* ssl, byte first, byte second) { key = 1; break; } + } + + /* ChaCha20-Poly1305 ECC cipher suites */ + if (first == CHACHA_BYTE) { + switch (second) { +#ifndef NO_DSA + /* ECDHE_ECDSA */ + case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 : + case TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + sig |= ssl->pkCurveOID == oid; + key |= ssl->eccTempKeySz == octets; + break; +#endif +#ifndef NO_RSA + /* ECDHE_RSA */ + case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 : + case TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 : + sig = 1; + key |= ssl->eccTempKeySz == octets; + break; +#endif + default: + sig = 1; + key = 1; + break; + } + } } return sig && key; diff --git a/tests/test.conf b/tests/test.conf index 5dda708b3..a7d2f5169 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -1,30 +1,3 @@ -# server TLSv1 DHE-RSA-CHACHA20-POLY1305 --v 1 --l DHE-RSA-CHACHA20-POLY1305 - -# client TLSv1 DHE-RSA-CHACHA20-POLY1305 --v 1 --l DHE-RSA-CHACHA20-POLY1305 - -# server TLSv1 ECDHE-EDCSA-CHACHA20-POLY1305 --v 1 --l ECDHE-ECDSA-CHACHA20-POLY1305 --c ./certs/server-ecc.pem --k ./certs/ecc-key.pem - -# client TLSv1 ECDHE-ECDSA-CHACHA20-POLY1305 --v 1 --l ECDHE-ECDSA-CHACHA20-POLY1305 --A ./certs/server-ecc.pem - -# server TLSv1 ECDHE-RSA-CHACHA20-POLY1305 --v 1 --l ECDHE-RSA-CHACHA20-POLY1305 - -# client TLSv1 ECDHE-RSA-CHACHA20-POLY1305 --v 1 --l ECDHE-RSA-CHACHA20-POLY1305 - # server TLSv1.1 DHE-RSA-CHACHA20-POLY1305 -v 2 -l DHE-RSA-CHACHA20-POLY1305 @@ -34,7 +7,7 @@ -l DHE-RSA-CHACHA20-POLY1305 # server TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305 --v 2 +-v 2 -l ECDHE-RSA-CHACHA20-POLY1305 # client TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305 @@ -61,7 +34,7 @@ -l DHE-RSA-CHACHA20-POLY1305 # server TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 --v 3 +-v 3 -l ECDHE-RSA-CHACHA20-POLY1305 # client TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 @@ -79,6 +52,33 @@ -l ECDHE-ECDSA-CHACHA20-POLY1305 -A ./certs/server-ecc.pem +# server TLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# client TLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# server TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# client TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# server TLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305-OLD +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-A ./certs/server-ecc.pem + # server SSLv3 RC4-SHA -v 0 -l RC4-SHA diff --git a/wolfcrypt/src/poly1305.c b/wolfcrypt/src/poly1305.c index 3cc86e1bb..0bb2697f5 100644 --- a/wolfcrypt/src/poly1305.c +++ b/wolfcrypt/src/poly1305.c @@ -127,6 +127,16 @@ } #endif + +static void U32TO64(word32 v, byte* p) { + XMEMSET(p, 0, 8); + p[0] = (v & 0xFF); + p[1] = (v >> 8) & 0xFF; + p[2] = (v >> 16) & 0xFF; + p[3] = (v >> 24) & 0xFF; +} + + static void poly1305_blocks(Poly1305* ctx, const unsigned char *m, size_t bytes) { @@ -550,5 +560,81 @@ int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) { } return 0; } + + +/* Takes in an initialized Poly1305 struct that has a key loaded and creates + a MAC (tag) using recent TLS AEAD padding scheme. + ctx : Initialized Poly1305 struct to use + additional : Additional data to use + addSz : Size of additional buffer + input : Input buffer to create tag from + sz : Size of input buffer + tag : Buffer to hold created tag + tagSz : Size of input tag buffer (must be at least + WC_POLY1305_MAC_SZ(16)) + */ +int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz, + byte* input, word32 sz, byte* tag, word32 tagSz) +{ + int ret; + byte padding[WC_POLY1305_PAD_SZ - 1]; + word32 paddingLen; + byte little64[8]; + + XMEMSET(padding, 0, sizeof(padding)); + + /* sanity check on arguments */ + if (ctx == NULL || input == NULL || tag == NULL || + tagSz < WC_POLY1305_MAC_SZ) { + return BAD_FUNC_ARG; + } + + if (additional == NULL && addSz > 0) { + return BAD_FUNC_ARG; + } + + /* additional data plus padding */ + if ((ret = wc_Poly1305Update(ctx, additional, addSz)) != 0) { + return ret; + } + paddingLen = -addSz & (WC_POLY1305_PAD_SZ - 1); + if (paddingLen) { + if ((ret = wc_Poly1305Update(ctx, padding, paddingLen)) != 0) { + return ret; + } + } + + /* input plus padding */ + if ((ret = wc_Poly1305Update(ctx, input, sz)) != 0) { + return ret; + } + paddingLen = -sz & (WC_POLY1305_PAD_SZ - 1); + if (paddingLen) { + if ((ret = wc_Poly1305Update(ctx, padding, paddingLen)) != 0) { + return ret; + } + } + + /* size of additional data and input as little endian 64 bit types */ + U32TO64(addSz, little64); + ret = wc_Poly1305Update(ctx, little64, sizeof(little64)); + if (ret) + { + return ret; + } + + U32TO64(sz, little64); + ret = wc_Poly1305Update(ctx, little64, sizeof(little64)); + if (ret) + { + return ret; + } + + /* Finalize the auth tag */ + ret = wc_Poly1305Final(ctx, tag); + + return ret; + +} #endif /* HAVE_POLY1305 */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c14ce259e..acbe5aac2 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -2090,6 +2090,31 @@ int poly1305_test(void) 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + const byte msg4[] = + { + 0xd3,0x1a,0x8d,0x34,0x64,0x8e,0x60,0xdb, + 0x7b,0x86,0xaf,0xbc,0x53,0xef,0x7e,0xc2, + 0xa4,0xad,0xed,0x51,0x29,0x6e,0x08,0xfe, + 0xa9,0xe2,0xb5,0xa7,0x36,0xee,0x62,0xd6, + 0x3d,0xbe,0xa4,0x5e,0x8c,0xa9,0x67,0x12, + 0x82,0xfa,0xfb,0x69,0xda,0x92,0x72,0x8b, + 0x1a,0x71,0xde,0x0a,0x9e,0x06,0x0b,0x29, + 0x05,0xd6,0xa5,0xb6,0x7e,0xcd,0x3b,0x36, + 0x92,0xdd,0xbd,0x7f,0x2d,0x77,0x8b,0x8c, + 0x98,0x03,0xae,0xe3,0x28,0x09,0x1b,0x58, + 0xfa,0xb3,0x24,0xe4,0xfa,0xd6,0x75,0x94, + 0x55,0x85,0x80,0x8b,0x48,0x31,0xd7,0xbc, + 0x3f,0xf4,0xde,0xf0,0x8e,0x4b,0x7a,0x9d, + 0xe5,0x76,0xd2,0x65,0x86,0xce,0xc6,0x4b, + 0x61,0x16 + }; + + byte additional[] = + { + 0x50,0x51,0x52,0x53,0xc0,0xc1,0xc2,0xc3, + 0xc4,0xc5,0xc6,0xc7 + }; + const byte correct[] = { 0xa8,0x06,0x1d,0xc1,0x30,0x51,0x36,0xc6, @@ -2109,6 +2134,12 @@ int poly1305_test(void) 0xc2,0x6b,0x33,0xb9,0x1c,0xcc,0x03,0x07 }; + const byte correct4[] = + { + 0x1a,0xe1,0x0b,0x59,0x4f,0x09,0xe2,0x6a, + 0x7e,0x90,0x2e,0xcb,0xd0,0x60,0x06,0x91 + }; + const byte key[] = { 0x85,0xd6,0xbe,0x78,0x57,0x55,0x6d,0x33, 0x7f,0x44,0x52,0xfe,0x42,0xd5,0x06,0xa8, @@ -2123,6 +2154,13 @@ int poly1305_test(void) 0x50,0x6f,0x6c,0x79,0x31,0x33,0x30,0x35 }; + const byte key4[] = { + 0x7b,0xac,0x2b,0x25,0x2d,0xb4,0x47,0xaf, + 0x09,0xb6,0x7a,0x55,0xa4,0xe9,0x55,0x84, + 0x0a,0xe1,0xd6,0x73,0x10,0x75,0xd9,0xeb, + 0x2a,0x93,0x75,0x78,0x3e,0xd5,0x53,0xff + }; + const byte* msgs[] = {msg, msg2, msg3}; word32 szm[] = {sizeof(msg),sizeof(msg2),sizeof(msg3)}; const byte* keys[] = {key, key2, key2}; @@ -2145,6 +2183,32 @@ int poly1305_test(void) return -61; } + /* Check TLS MAC function from 2.8.2 https://tools.ietf.org/html/rfc7539 */ + XMEMSET(tag, 0, sizeof(tag)); + ret = wc_Poly1305SetKey(&enc, key4, sizeof(key4)); + if (ret != 0) + return -62; + + ret = wc_Poly1305_MAC(&enc, additional, sizeof(additional), + (byte*)msg4, sizeof(msg4), tag, sizeof(tag)); + if (ret != 0) + return -63; + + if (memcmp(tag, correct4, sizeof(tag))) + return -64; + + /* Check fail of TLS MAC function if altering additional data */ + XMEMSET(tag, 0, sizeof(tag)); + additional[0] = additional[0] + 1; + ret = wc_Poly1305_MAC(&enc, additional, sizeof(additional), + (byte*)msg4, sizeof(msg4), tag, sizeof(tag)); + if (ret != 0) + return -65; + + if (memcmp(tag, correct4, sizeof(tag)) == 0) + return -66; + + return 0; } #endif /* HAVE_POLY1305 */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index b36af64d8..03b72cf77 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -521,6 +521,18 @@ typedef byte word24[3]; #endif /* NO_SHA */ #endif #endif + #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256) \ + && !defined(NO_OLD_POLY1305) + #ifdef HAVE_ECC + #define BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + #ifndef NO_RSA + #define BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + #endif + #endif + #if !defined(NO_DH) && !defined(NO_RSA) + #define BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 + #endif + #endif #endif /* !WOLFSSL_MAX_STRENGTH */ @@ -787,9 +799,14 @@ enum { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0xc4, /* chacha20-poly1305 suites first byte is 0xCC (CHACHA_BYTE) */ - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0x13, - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0x14, - TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0x15, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xa8, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xa9, + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xaa, + + /* chacha20-poly1305 earlier version of nonce and padding (CHACHA_BYTE) */ + TLS_ECDHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 = 0x13, + TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 = 0x14, + TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 = 0x15, /* Renegotiation Indication Extension Special Suite */ TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0xff @@ -803,7 +820,7 @@ enum { enum Misc { - ECC_BYTE = 0xC0, /* ECC first cipher suite byte */ + ECC_BYTE = 0xC0, /* ECC first cipher suite byte */ QSH_BYTE = 0xD0, /* Quantum-safe Handshake cipher suite */ CHACHA_BYTE = 0xCC, /* ChaCha first cipher suite */ @@ -912,15 +929,21 @@ enum Misc { AES_IV_SIZE = 16, /* always block size */ AES_128_KEY_SIZE = 16, /* for 128 bit */ - AEAD_SEQ_OFFSET = 4, /* Auth Data: Sequence number */ - AEAD_TYPE_OFFSET = 8, /* Auth Data: Type */ - AEAD_VMAJ_OFFSET = 9, /* Auth Data: Major Version */ - AEAD_VMIN_OFFSET = 10, /* Auth Data: Minor Version */ - AEAD_LEN_OFFSET = 11, /* Auth Data: Length */ - AEAD_AUTH_DATA_SZ = 13, /* Size of the data to authenticate */ - 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, + AEAD_SEQ_OFFSET = 4, /* Auth Data: Sequence number */ + AEAD_TYPE_OFFSET = 8, /* Auth Data: Type */ + AEAD_VMAJ_OFFSET = 9, /* Auth Data: Major Version */ + AEAD_VMIN_OFFSET = 10, /* Auth Data: Minor Version */ + AEAD_LEN_OFFSET = 11, /* Auth Data: Length */ + AEAD_AUTH_DATA_SZ = 13, /* Size of the data to authenticate */ + AESGCM_IMP_IV_SZ = 4, /* Size of GCM/CCM AEAD implicit IV */ + AESGCM_EXP_IV_SZ = 8, /* Size of GCM/CCM AEAD explicit IV */ + AESGCM_NONCE_SZ = AESGCM_EXP_IV_SZ + AESGCM_IMP_IV_SZ, + + CHACHA20_IMP_IV_SZ = 12, /* Size of ChaCha20 AEAD implicit IV */ + CHACHA20_NONCE_SZ = 12, /* Size of ChacCha20 nonce */ + CHACHA20_OLD_OFFSET = 8, /* Offset for seq # in old poly1305 */ + + /* For any new implicit/explicit IV size adjust AEAD_MAX_***_SZ */ AES_GCM_AUTH_SZ = 16, /* AES-GCM Auth Tag length */ AES_CCM_16_AUTH_SZ = 16, /* AES-CCM-16 Auth Tag length */ @@ -933,7 +956,7 @@ enum Misc { CHACHA20_256_KEY_SIZE = 32, /* for 256 bit */ CHACHA20_128_KEY_SIZE = 16, /* for 128 bit */ - CHACHA20_IV_SIZE = 8, /* 64 bits for iv */ + CHACHA20_IV_SIZE = 12, /* 96 bits for iv */ POLY1305_AUTH_SZ = 16, /* 128 bits */ @@ -992,6 +1015,17 @@ enum Misc { }; +/* Set max implicit IV size for AEAD cipher suites */ +#ifdef HAVE_CHACHA + #define AEAD_MAX_IMP_SZ 12 +#else + #define AEAD_MAX_IMP_SZ 4 +#endif + +/* Set max explicit IV size for AEAD cipher suites */ +#define AEAD_MAX_EXP_SZ 8 + + #ifndef WOLFSSL_MAX_SUITE_SZ #define WOLFSSL_MAX_SUITE_SZ 300 /* 150 suites for now! */ @@ -1438,18 +1472,20 @@ typedef struct WOLFSSL_DTLS_CTX { #endif /* WOLFSSL_DTLS */ +#define MAX_WRITE_IV_SZ 16 /* max size of client/server write_IV */ + /* keys and secrets */ typedef struct Keys { byte client_write_MAC_secret[MAX_DIGEST_SIZE]; /* max sizes */ byte server_write_MAC_secret[MAX_DIGEST_SIZE]; byte client_write_key[AES_256_KEY_SIZE]; /* max sizes */ byte server_write_key[AES_256_KEY_SIZE]; - byte client_write_IV[AES_IV_SIZE]; /* max sizes */ - byte server_write_IV[AES_IV_SIZE]; + byte client_write_IV[MAX_WRITE_IV_SZ]; /* max sizes */ + byte server_write_IV[MAX_WRITE_IV_SZ]; #ifdef HAVE_AEAD - 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]; + byte aead_exp_IV[AEAD_MAX_EXP_SZ]; + byte aead_enc_imp_IV[AEAD_MAX_IMP_SZ]; + byte aead_dec_imp_IV[AEAD_MAX_IMP_SZ]; #endif word32 peer_sequence_number; diff --git a/wolfssl/wolfcrypt/poly1305.h b/wolfssl/wolfcrypt/poly1305.h index 0e76d063d..55369cb4a 100644 --- a/wolfssl/wolfcrypt/poly1305.h +++ b/wolfssl/wolfcrypt/poly1305.h @@ -46,9 +46,11 @@ enum { POLY1305 = 7, POLY1305_BLOCK_SIZE = 16, POLY1305_DIGEST_SIZE = 16, - POLY1305_PAD_SIZE = 56 }; +#define WC_POLY1305_PAD_SZ 16 +#define WC_POLY1305_MAC_SZ 16 + /* Poly1305 state */ typedef struct Poly1305 { #if defined(POLY130564) @@ -71,7 +73,8 @@ typedef struct Poly1305 { WOLFSSL_API int wc_Poly1305SetKey(Poly1305* poly1305, const byte* key, word32 kySz); WOLFSSL_API int wc_Poly1305Update(Poly1305* poly1305, const byte*, word32); WOLFSSL_API int wc_Poly1305Final(Poly1305* poly1305, byte* tag); - +WOLFSSL_API int wc_Poly1305_MAC(Poly1305* ctx, byte* additional, word32 addSz, + byte* input, word32 sz, byte* tag, word32 tagSz); #ifdef __cplusplus } /* extern "C" */ #endif