diff --git a/cyassl/internal.h b/cyassl/internal.h index 689ca6a9d..dbb396fa4 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -468,9 +468,20 @@ void c32to24(word32 in, word24 out); #ifdef HAVE_CHACHA #define CHACHA20_BLOCK_SIZE 16 - #define BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - #define BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 - #define BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + /* ChaCha - Poly AEAD suites */ + #if defined(HAVE_POLY1305) && !defined(NO_SHA256) + #if defined(HAVE_ECC) + #if !defined(NO_RSA) + #define BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + #endif + #if !defined(NO_DSA) + #define BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + #endif + #endif + #if !defined(NO_DH) && !defined(NO_RSA) + #define BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + #endif + #endif /* end of ChaCha - Poly AEAD suites */ #endif #if defined(BUILD_AESGCM) || defined(HAVE_AESCCM) || defined(HAVE_CHACHA) @@ -1704,6 +1715,10 @@ typedef struct Options { byte usingNonblock; /* set when using nonblocking socket */ byte saveArrays; /* save array Memory for user get keys or psk */ +#ifdef HAVE_POLY1305 + byte oldPoly; /* set when to use old rfc way of poly*/ +#endif + #ifndef NO_PSK byte havePSK; /* psk key set by user */ psk_client_callback client_psk_cb; diff --git a/cyassl/ssl.h b/cyassl/ssl.h index 19a19a15a..7109b0726 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -217,6 +217,10 @@ CYASSL_API int CyaSSL_use_RSAPrivateKey_file(CYASSL*, const char*, int); const char*, int); #endif +#ifdef HAVE_POLY1305 + CYASSL_API int CyaSSL_use_old_poly(CYASSL*, int); +#endif + #ifdef HAVE_NTRU CYASSL_API int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX*, const char*); /* load NTRU private key blob */ diff --git a/examples/client/client.c b/examples/client/client.c index 6c268e65d..65aa0f837 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -611,6 +611,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) #endif ssl = CyaSSL_new(ctx); + if (ssl == NULL) err_sys("unable to get SSL object"); if (doDTLS) { @@ -622,6 +623,15 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args) else { tcp_connect(&sockfd, host, port, 0); } + +#ifdef HAVE_POLY1305 + /* use old poly to connect with google server */ + if (!XMEMCMP(domain, "www.google.com", 15)) { + if (CyaSSL_use_old_poly(ssl, 1) != 0) + err_sys("unable to set to old poly"); + } +#endif + CyaSSL_set_fd(ssl, sockfd); #ifdef HAVE_CRL if (CyaSSL_EnableCRL(ssl, CYASSL_CRL_CHECKALL) != SSL_SUCCESS) diff --git a/src/internal.c b/src/internal.c index 52d60a4f9..4f1fd1980 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4567,10 +4567,6 @@ static int DoHandShakeMsg(CYASSL* ssl, byte* input, word32* inOutIdx, CYASSL_ENTER("DoHandShakeMsg()"); - /* changes the pointer for CHACHA aead */ - if (ssl->specs.bulk_cipher_algorithm == cyassl_chacha && *inOutIdx > 7) - *inOutIdx -= 8; - if (GetHandShakeHeader(ssl, input, inOutIdx, &type, &size) != 0) return PARSE_ERROR; @@ -4757,105 +4753,333 @@ static INLINE void AeadIncrementExpIV(CYASSL* ssl) #ifdef HAVE_POLY1305 -#ifndef OLD_POLY /*more recent rfc's concatonate input for poly1305 differently*/ - -static int Poly1305Tag(CYASSL* ssl, byte* additional, const byte* out, byte* cipher, - word16 sz, byte* tag) +/*more recent rfc's concatonate input for poly1305 differently*/ +static int Poly1305Tag(CYASSL* ssl, byte* additional, const byte* out, + byte* cipher, word16 sz, byte* tag) { - int padding2 = (sz - ssl->specs.aead_mac_size); - if ((sz - ssl->specs.aead_mac_size) % 16 != 0) { - padding2 += - (16 - (sz - ssl->specs.aead_mac_size) % 16); - } - - byte p[CHACHA20_BLOCK_SIZE + padding2 + 16]; - XMEMSET(p, 0, CHACHA20_BLOCK_SIZE + padding2 + 16); + int ret = 0; + int paddingSz = 0; + int msglen = (sz - ssl->specs.aead_mac_size); + word32 keySz = 32; + byte padding[16]; - /* create input to poly1305 */ - XMEMCPY(p, additional, CHACHA20_BLOCK_SIZE); - XMEMCPY((p + CHACHA20_BLOCK_SIZE), out, - sz - ssl->specs.aead_mac_size); + if (msglen < 0) + return INPUT_CASE_ERROR; - /* add size of AD and size of cipher to poly input */ - (p + CHACHA20_BLOCK_SIZE + padding2)[0] = - (CHACHA20_BLOCK_SIZE); + XMEMSET(padding, 0, sizeof(padding)); - /* 32 bit size of cipher to 64 bit endian */ - ((p + CHACHA20_BLOCK_SIZE + padding2))[8] = - (sz - ssl->specs.aead_mac_size) & 0xff; - - ((p + CHACHA20_BLOCK_SIZE + padding2))[9] = - ((sz - ssl->specs.aead_mac_size) >> 8) & 0xff; - - ((p + CHACHA20_BLOCK_SIZE + padding2))[10] = - ((sz - ssl->specs.aead_mac_size) >>16) & 0xff; - - ((p + CHACHA20_BLOCK_SIZE + padding2))[11] = - ((sz - ssl->specs.aead_mac_size) >>24) & 0xff; + if ((ret = Poly1305SetKey(ssl->encrypt.poly1305, cipher, keySz)) != 0) + return ret; - /* generate tag */ - Poly1305SetKey(ssl->encrypt.poly1305, cipher, 32); - Poly1305Update(ssl->encrypt.poly1305, p, - CHACHA20_BLOCK_SIZE + padding2 + 16); - Poly1305Final(ssl->encrypt.poly1305, tag); + /* additional input to poly1305 */ + if ((ret = Poly1305Update(ssl->encrypt.poly1305, additional, + CHACHA20_BLOCK_SIZE)) != 0) + return ret; - return 0; + /* cipher input */ + if ((ret = Poly1305Update(ssl->encrypt.poly1305, out, msglen)) != 0) + return ret; + + /* handle padding for cipher input */ + if (msglen % 16 != 0) { + paddingSz = (16 - (sz - ssl->specs.aead_mac_size) % 16); + if (paddingSz < 0) + return INPUT_CASE_ERROR; + + if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding, paddingSz)) + != 0) + return ret; + } + + /* add size of AD and size of cipher to poly input */ + XMEMSET(padding, 0, sizeof(padding)); + padding[0] = CHACHA20_BLOCK_SIZE; + + /* 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 = Poly1305Update(ssl->encrypt.poly1305, padding, sizeof(padding))) + != 0) + return ret; + + /* generate tag */ + if ((ret = Poly1305Final(ssl->encrypt.poly1305, tag)) != 0) + return ret; + + return ret; } -#else - /** * Used for the older version of creating AEAD tags with Poly1305 */ -static int Poly1305Tag(CYASSL* ssl, byte* additional, const byte* out, byte* cipher, - word16 sz, byte* tag) +static int Poly1305TagOld(CYASSL* ssl, byte* additional, const byte* out, + byte* cipher, word16 sz, byte* tag) { - byte p[AEAD_AUTH_DATA_SZ + 16 + - (sz - ssl->specs.aead_mac_size)]; - XMEMSET(p, 0, sizeof(p)); + int ret = 0; + int msglen = (sz - ssl->specs.aead_mac_size); + word32 keySz = 32; + byte padding[8]; /* used to temporarly store lengths */ #ifdef CHACHA_AEAD_TEST printf("Using old version of poly1305 input.\n"); #endif - /* create input to poly1305 */ - XMEMCPY(p, additional, AEAD_AUTH_DATA_SZ); - - (p + AEAD_AUTH_DATA_SZ - 2)[0] = ((sz - ssl->specs.aead_mac_size)>>8) & 0xff; - (p + AEAD_AUTH_DATA_SZ - 2)[1] = (sz - ssl->specs.aead_mac_size) & 0xff; - - (p + AEAD_AUTH_DATA_SZ)[0] = AEAD_AUTH_DATA_SZ; + if (msglen < 0) + return INPUT_CASE_ERROR; - XMEMCPY((p + AEAD_AUTH_DATA_SZ + 8), out, - sz - ssl->specs.aead_mac_size); + if ((ret = Poly1305SetKey(ssl->encrypt.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 = Poly1305Update(ssl->encrypt.poly1305, additional, + AEAD_AUTH_DATA_SZ)) != 0) + return ret; + + /* length of additional input plus padding */ + XMEMSET(padding, 0, sizeof(padding)); + padding[0] = AEAD_AUTH_DATA_SZ; + if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding, + sizeof(padding))) != 0) + return ret; - /* 32 bit size of cipher to 64 bit endian */ - (p + AEAD_AUTH_DATA_SZ + sz - ssl->specs.aead_mac_size - + 8)[0] = - (sz - ssl->specs.aead_mac_size) & 0xff; - - (p + AEAD_AUTH_DATA_SZ + sz - ssl->specs.aead_mac_size - + 8)[1] = - ((sz - ssl->specs.aead_mac_size) >> 8) & 0xff; - - (p + AEAD_AUTH_DATA_SZ + sz - ssl->specs.aead_mac_size - + 8)[2] = - ((sz - ssl->specs.aead_mac_size) >>16) & 0xff; - - (p + AEAD_AUTH_DATA_SZ + sz - ssl->specs.aead_mac_size - + 8)[3] = - ((sz - ssl->specs.aead_mac_size) >>24) & 0xff; + /* add cipher info and then its length */ + XMEMSET(padding, 0, sizeof(padding)); + if ((ret = Poly1305Update(ssl->encrypt.poly1305, out, msglen)) != 0) + return ret; - /* generate tag */ - Poly1305SetKey(ssl->encrypt.poly1305, cipher, 32); - Poly1305Update(ssl->encrypt.poly1305, p, sizeof(p)); - Poly1305Final(ssl->encrypt.poly1305, tag); + /* 32 bit size of cipher to 64 bit endian */ + padding[0] = msglen & 0xff; + padding[1] = (msglen >> 8) & 0xff; + padding[2] = (msglen >> 16) & 0xff; + padding[3] = (msglen >> 24) & 0xff; + if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding, sizeof(padding))) + != 0) + return ret; - return 0; + /* generate tag */ + if ((ret = Poly1305Final(ssl->encrypt.poly1305, tag)) != 0) + return ret; + + return ret; } -#endif /*OLD_POLY*/ #endif /*HAVE_POLY1305*/ + +#ifdef HAVE_CHACHA +static int ChachaAEADEncrypt(CYASSL* ssl, byte* out, const byte* input, + word16 sz) +{ + int offset = 5; /*where to find type,version in record header */ + const byte* additionalSrc = input - offset; + int ret = 0; + byte tag[ssl->specs.aead_mac_size]; + byte additional[CHACHA20_BLOCK_SIZE]; + byte nonce[AEAD_NONCE_SZ]; + byte cipher[32]; /* generated key for poly1305 */ + + XMEMSET(tag, 0, sizeof(tag)); + XMEMSET(nonce, 0, AEAD_NONCE_SZ); + XMEMSET(cipher, 0, sizeof(cipher)); + XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE); + + /* get nonce */ + c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ + + AEAD_SEQ_OFFSET); + + /* opaque SEQ number stored for AD */ + c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET); + + /* Store the type, version. Unfortunately, they are in + * the input buffer ahead of the plaintext. */ + #ifdef CYASSL_DTLS + if (ssl->options.dtls) { + c16toa(ssl->keys.dtls_epoch, additional); + additionalSrc -= DTLS_HANDSHAKE_EXTRA; + } + #endif + + XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3); + + #ifdef CHACHA_AEAD_TEST + int i; + printf("Encrypt Additional : "); + for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) { + printf("%02x", additional[i]); + } + printf("\n\n"); + printf("input before encryption :\n"); + for (i = 0; i < sz; i++) { + printf("%02x", input[i]); + if ((i + 1) % 16 == 0) + printf("\n"); + } + printf("\n"); + #endif + + /* set the nonce for chacha and get poly1305 key */ + if ((ret = Chacha_SetIV(ssl->encrypt.chacha, nonce, 0)) != 0) + return ret; + + if ((ret = Chacha_Process(ssl->encrypt.chacha, cipher, + cipher, 32)) != 0) + return ret; + + /* encrypt the plain text */ + if ((ret = Chacha_Process(ssl->encrypt.chacha, out, input, + sz - ssl->specs.aead_mac_size)) != 0) + return ret; + + #ifdef HAVE_POLY1305 + /* 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) + return ret; + } + else { + if ((ret = Poly1305Tag(ssl, additional, (const byte* )out, + cipher, sz, tag)) != 0) + return ret; + } + #endif + + /* append tag to ciphertext */ + XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag)); + + AeadIncrementExpIV(ssl); + XMEMSET(nonce, 0, AEAD_NONCE_SZ); + + #ifdef CHACHA_AEAD_TEST + printf("mac tag :\n"); + for (i = 0; i < 16; i++) { + printf("%02x", tag[i]); + if ((i + 1) % 16 == 0) + printf("\n"); + } + printf("\n\noutput after encrypt :\n"); + for (i = 0; i < sz; i++) { + printf("%02x", out[i]); + if ((i + 1) % 16 == 0) + printf("\n"); + } + printf("\n"); + #endif + + return ret; +} + +static int ChachaAEADDecrypt(CYASSL* ssl, byte* plain, const byte* input, + word16 sz) +{ + byte additional[CHACHA20_BLOCK_SIZE]; + byte nonce[AEAD_NONCE_SZ]; + byte tag[ssl->specs.aead_mac_size]; + byte cipher[32]; /* generated key for mac */ + int i; + 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); + + #ifdef CHACHA_AEAD_TEST + printf("input before decrypt :\n"); + for (i = 0; i < sz; i++) { + printf("%02x", input[i]); + if ((i + 1) % 16 == 0) + printf("\n"); + } + printf("\n"); + #endif + + /* get nonce */ + c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ + + AEAD_SEQ_OFFSET); + + /* sequence number field is 64-bits, we only use 32-bits */ + c32toa(GetSEQIncrement(ssl, 1), additional + 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; + + /* Store the type, version. */ + #ifdef CYASSL_DTLS + if (ssl->options.dtls) + c16toa(ssl->keys.dtls_state.curEpoch, additional); + #endif + + + #ifdef CHACHA_AEAD_TEST + printf("Decrypt Additional : "); + for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) { + printf("%02x", additional[i]); + } + printf("\n\n"); + #endif + + /* set nonce and get poly1305 key */ + if ((ret = Chacha_SetIV(ssl->decrypt.chacha, nonce, 0)) != 0) + return ret; + + if ((ret = Chacha_Process(ssl->decrypt.chacha, cipher, + cipher, sizeof(cipher))) != 0) + return ret; + + #ifdef HAVE_POLY1305 + /* 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) + return ret; + } + else { + if ((ret = Poly1305Tag(ssl, additional, input, cipher, + sz, tag)) != 0) + return ret; + } + #endif + + /* check mac sent along with packet */ + ret = 0; + for (i = 0; i < ssl->specs.aead_mac_size; i++) { + if ((input + sz - ssl->specs.aead_mac_size)[i] != tag[i]) + ret = 1; + } + + if (ret == 1) { + CYASSL_MSG("Mac did not match"); + SendAlert(ssl, alert_fatal, bad_record_mac); + XMEMSET(nonce, 0, AEAD_NONCE_SZ); + return VERIFY_MAC_ERROR; + } + + /* if mac was good decrypt message */ + if ((ret = Chacha_Process(ssl->decrypt.chacha, plain, input, + sz - ssl->specs.aead_mac_size)) != 0) + return ret; + + + #ifdef CHACHA_AEAD_TEST + printf("plain after decrypt :\n"); + for (i = 0; i < sz; i++) { + printf("%02x", plain[i]); + if ((i + 1) % 16 == 0) + printf("\n"); + } + printf("\n"); + #endif + + return ret; +} +#endif /* HAVE_CHACHA */ #endif @@ -4993,89 +5217,7 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word16 sz) #ifdef HAVE_CHACHA case cyassl_chacha: - { - const byte* additionalSrc = input - 5; - byte tag[16]; - byte additional[CHACHA20_BLOCK_SIZE]; - byte nonce[AEAD_NONCE_SZ]; - byte cipher[32]; /* generated key for poly1305 */ - XMEMSET(tag, 0, ssl->specs.aead_mac_size); - XMEMSET(nonce, 0, AEAD_NONCE_SZ); - XMEMSET(cipher, 0, sizeof(cipher)); - XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE); - - /* get nonce */ -#ifndef OLD_POLY - /* new rfc of chacha uses salt in nonce else use 0 */ - XMEMCPY(nonce, ssl->keys.aead_enc_imp_IV, AEAD_IMP_IV_SZ); -#endif - c32toa(ssl->keys.sequence_number, nonce + AEAD_IMP_IV_SZ - + AEAD_SEQ_OFFSET); - - /* opaque SEQ number stored for AD */ - c32toa(GetSEQIncrement(ssl, 0), additional + AEAD_SEQ_OFFSET); - - /* Store the type, version. Unfortunately, they are in - * the input buffer ahead of the plaintext. */ - #ifdef CYASSL_DTLS - if (ssl->options.dtls) { - c16toa(ssl->keys.dtls_epoch, additional); - additionalSrc -= DTLS_HANDSHAKE_EXTRA; - } - #endif - - XMEMCPY(additional + AEAD_TYPE_OFFSET, additionalSrc, 3); - -#ifdef CHACHA_AEAD_TEST - int i; - printf("Encrypt Additional : "); - for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) { - printf("%02x", additional[i]); - } - printf("\n\n"); - printf("input before encryption :\n"); - for (i = 0; i < sz; i++) { - printf("%02x", input[i]); - if ((i + 1) % 16 == 0) - printf("\n"); - } - printf("\n"); -#endif - - /* set the nonce for chacha and get poly1305 key */ - Chacha_SetIV(ssl->encrypt.chacha, nonce, 0); - Chacha_Process(ssl->encrypt.chacha, cipher, cipher, 32); - - /* encrypt the plain text */ - Chacha_Process(ssl->encrypt.chacha, out, input, - sz - ssl->specs.aead_mac_size); - - /* get the tag : future use of hmac could go here*/ - Poly1305Tag(ssl, additional, (const byte* )out, cipher, sz, tag); - - /* append tag to ciphertext */ - XMEMCPY(out + sz - ssl->specs.aead_mac_size, tag, sizeof(tag)); - - AeadIncrementExpIV(ssl); - XMEMSET(nonce, 0, AEAD_NONCE_SZ); - - #ifdef CHACHA_AEAD_TEST - printf("mac tag :\n"); - for (i = 0; i < 16; i++) { - printf("%02x", tag[i]); - if ((i + 1) % 16 == 0) - printf("\n"); - } - printf("\n\noutput after encrypt :\n"); - for (i = 0; i < sz; i++) { - printf("%02x", out[i]); - if ((i + 1) % 16 == 0) - printf("\n"); - } - printf("\n"); - #endif - } - break; /* end of chacha-poly1305 encrypt process */ + return ChachaAEADEncrypt(ssl, out, input, sz); #endif #ifdef HAVE_NULL_CIPHER @@ -5225,96 +5367,7 @@ static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, #ifdef HAVE_CHACHA case cyassl_chacha: - { - byte additional[CHACHA20_BLOCK_SIZE]; - byte nonce[AEAD_NONCE_SZ]; - byte tag[16]; - byte cipher[32]; - int i, ret; - - XMEMSET(tag, 0, 16); - XMEMSET(cipher, 0, sizeof(cipher)); - XMEMSET(nonce, 0, AEAD_NONCE_SZ); - XMEMSET(additional, 0, CHACHA20_BLOCK_SIZE); - - #ifdef CHACHA_AEAD_TEST - printf("input before decrypt :\n"); - for (i = 0; i < sz; i++) { - printf("%02x", input[i]); - if ((i + 1) % 16 == 0) - printf("\n"); - } - printf("\n"); - #endif - - /* get nonce */ -#ifndef OLD_POLY - XMEMCPY(nonce, ssl->keys.aead_dec_imp_IV, AEAD_IMP_IV_SZ); -#endif - c32toa(ssl->keys.peer_sequence_number, nonce + AEAD_IMP_IV_SZ - + AEAD_SEQ_OFFSET); - - /* sequence number field is 64-bits, we only use 32-bits */ - c32toa(GetSEQIncrement(ssl, 1), additional + 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; - - /* Store the type, version. */ - #ifdef CYASSL_DTLS - if (ssl->options.dtls) - c16toa(ssl->keys.dtls_state.curEpoch, additional); - #endif - - -#ifdef CHACHA_AEAD_TEST - printf("Decrypt Additional : "); - for (i = 0; i < CHACHA20_BLOCK_SIZE; i++) { - printf("%02x", additional[i]); - } - printf("\n\n"); -#endif - - /* set nonce and get poly1305 key */ - Chacha_SetIV(ssl->decrypt.chacha, nonce, 0); - Chacha_Process(ssl->decrypt.chacha, cipher, cipher, 32); - - /* get the tag : potential future use of hmac could go here */ - Poly1305Tag(ssl, additional, input, cipher, sz, tag); - - /* check mac sent along with packet */ - ret = 0; - for (i = 0; i < ssl->specs.aead_mac_size; i++) { - if ((input + sz - ssl->specs.aead_mac_size)[i] != tag[i]) - ret = 1; - } - - if (ret == 1) { - CYASSL_MSG("Mac did not match"); - SendAlert(ssl, alert_fatal, bad_record_mac); - XMEMSET(nonce, 0, AEAD_NONCE_SZ); - return VERIFY_MAC_ERROR; - } - - /* if mac was good decrypt message */ - Chacha_Process(ssl->decrypt.chacha, plain, input, - sz - ssl->specs.aead_mac_size); - - - #ifdef CHACHA_AEAD_TEST - printf("plain after decrypt :\n"); - for (i = 0; i < sz; i++) { - printf("%02x", plain[i]); - if ((i + 1) % 16 == 0) - printf("\n"); - } - printf("\n"); - #endif - - } - break; + return ChachaAEADDecrypt(ssl, plain, input, sz); #endif #ifdef HAVE_NULL_CIPHER @@ -5667,7 +5720,8 @@ int DoApplicationData(CYASSL* ssl, byte* input, word32* inOutIdx) ivExtra = ssl->specs.block_size; } else if (ssl->specs.cipher_type == aead) { - ivExtra = AEAD_EXP_IV_SZ; + if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha) + ivExtra = AEAD_EXP_IV_SZ; } dataSz = msgSz - ivExtra - ssl->keys.padSz; @@ -6058,7 +6112,8 @@ int ProcessReply(CYASSL* ssl) if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) ssl->buffers.inputBuffer.idx += ssl->specs.block_size; /* go past TLSv1.1 IV */ - if (ssl->specs.cipher_type == aead) + if (ssl->specs.cipher_type == aead && + ssl->specs.bulk_cipher_algorithm != cyassl_chacha) ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ; #endif /* ATOMIC_USER */ } @@ -6075,7 +6130,8 @@ int ProcessReply(CYASSL* ssl) if (ssl->options.tls1_1 && ssl->specs.cipher_type == block) ssl->buffers.inputBuffer.idx += ssl->specs.block_size; /* go past TLSv1.1 IV */ - if (ssl->specs.cipher_type == aead) + if (ssl->specs.cipher_type == aead && + ssl->specs.bulk_cipher_algorithm != cyassl_chacha) ssl->buffers.inputBuffer.idx += AEAD_EXP_IV_SZ; ret = VerifyMac(ssl, ssl->buffers.inputBuffer.buffer + @@ -6507,13 +6563,9 @@ static int BuildMessage(CYASSL* ssl, byte* output, int outSz, #ifdef HAVE_AEAD if (ssl->specs.cipher_type == aead) { - if (ssl->specs.bulk_cipher_algorithm == cyassl_chacha) { - /* chacha aead does not send exp iv with message */ - ivSz = 0; - } - else { + if (ssl->specs.bulk_cipher_algorithm != cyassl_chacha) ivSz = AEAD_EXP_IV_SZ; - } + sz += (ivSz + ssl->specs.aead_mac_size - digestSz); XMEMCPY(iv, ssl->keys.aead_exp_IV, AEAD_EXP_IV_SZ); } @@ -7782,15 +7834,15 @@ static const char* const cipher_names[] = #endif #ifdef BUILD_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - "ECDHE-RSA-CHACHA20-256-POLY1305-SHA256", + "ECDHE-RSA-CHACHA20-POLY1305", #endif #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 - "ECDHE-ECDSA-CHACHA20-256-POLY1305-SHA256", + "ECDHE-ECDSA-CHACHA20-POLY1305", #endif #ifdef BUILD_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - "DHE-RSA-CHACHA20-256-POLY1305-SHA256", + "DHE-RSA-CHACHA20-POLY1305", #endif }; diff --git a/src/ssl.c b/src/ssl.c index dd99d8f30..1b99e98fd 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -194,6 +194,16 @@ void CyaSSL_free(CYASSL* ssl) CYASSL_LEAVE("SSL_free", 0); } +#ifdef HAVE_POLY1305 +/* set if to use old poly 1 for yes 0 to use new poly */ +int CyaSSL_use_old_poly(CYASSL* ssl, int value) +{ + CYASSL_ENTER("SSL_use_old_poly"); + ssl->options.oldPoly = value; + CYASSL_LEAVE("SSL_use_old_poly", 0); + return 0; +} +#endif int CyaSSL_set_fd(CYASSL* ssl, int fd) { diff --git a/tests/test-dtls.conf b/tests/test-dtls.conf index cc3a6aeb5..887afb18d 100644 --- a/tests/test-dtls.conf +++ b/tests/test-dtls.conf @@ -1,3 +1,69 @@ +# server DTLSv1 DHE-RSA-CHACHA20-POLY1305 +-u +-v 2 +-l DHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1 DHE-RSA-CHACHA20-POLY1305 +-u +-v 2 +-l DHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1 ECDHE-RSA-CHACHA20-POLY1305 +-u +-v 2 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1 ECDHE-RSA-CHACHA20-POLY1305 +-u +-v 2 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1 ECDHE-EDCSA-CHACHA20-POLY1305 +-u +-v 2 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1 ECDHE-ECDSA-CHACHA20-POLY1305 +-u +-v 2 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/server-ecc.pem + +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305 +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305 +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/server-ecc.pem + # server DTLSv1 RC4-SHA -u -v 2 diff --git a/tests/test.conf b/tests/test.conf index c5de20a15..b3656f112 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -1,3 +1,84 @@ +# 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 + +# client TLSv1.1 DHE-RSA-CHACHA20-POLY1305 +-v 2 +-l DHE-RSA-CHACHA20-POLY1305 + +# server TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305 +-v 2 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# client TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305 +-v 2 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# server TLSv1.1 ECDHE-EDCSA-CHACHA20-POLY1305 +-v 2 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.1 ECDHE-ECDSA-CHACHA20-POLY1305 +-v 2 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/server-ecc.pem + +# server TLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# client TLSv1.2 DHE-RSA-CHACHA20-POLY1305 +-v 3 +-l DHE-RSA-CHACHA20-POLY1305 + +# server TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# client TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305 + +# server TLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305 +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305 +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/server-ecc.pem + # server SSLv3 RC4-SHA -v 0 -l RC4-SHA @@ -349,17 +430,6 @@ -l ECDHE-ECDSA-RC4-SHA -A ./certs/server-ecc.pem -# server TLSv1.1 ECDHE-EDCSA-CHACHA20-POLY1305 --v 2 --l ECDHE-ECDSA-CHACHA20-256-POLY1305-SHA256 --c ./certs/server-ecc.pem --k ./certs/ecc-key.pem - -# client TLSv1.1 ECDHE-ECDSA-CHACHA20-POLY1305 --v 2 --l ECDHE-ECDSA-CHACHA20-256-POLY1305-SHA256 --A ./certs/server-ecc.pem - # server TLSv1.1 ECDHE-ECDSA-DES3 -v 2 -l ECDHE-ECDSA-DES-CBC3-SHA @@ -729,14 +799,6 @@ -v 3 -l ECDHE-RSA-AES256-SHA384 -# server TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305 --v 2 --l ECDHE-RSA-CHACHA20-256-POLY1305-SHA256 - -# server TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305 --v 2 --l ECDHE-RSA-CHACHA20-256-POLY1305-SHA256 - # server TLSv1.2 ECDHE-ECDSA-AES256-SHA384 -v 3 -l ECDHE-ECDSA-AES256-SHA384 @@ -1053,14 +1115,6 @@ -v 1 -l DHE-RSA-AES128-SHA -# server TLSv1 DHE-RSA-CHACHA20-POLY1305 --v 1 --l DHE-RSA-CHACHA20-256-POLY1305-SHA256 - -# server TLSv1 DHE-RSA-CHACHA20-POLY1305 --v 1 --l DHE-RSA-CHACHA20-256-POLY1305-SHA256 - # server TLSv1 DHE AES256 -v 1 -l DHE-RSA-AES256-SHA