Merge pull request #280 from JacobBarthelmeh/master

Update ChaCha20-Poly1305 cipher suites
This commit is contained in:
toddouska
2016-01-29 14:12:53 -08:00
11 changed files with 732 additions and 293 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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
}
}

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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