diff --git a/configure.ac b/configure.ac index af2256e79..dbd2716fb 100644 --- a/configure.ac +++ b/configure.ac @@ -410,7 +410,7 @@ AC_ARG_ENABLE([poly1305], if test "$ENABLED_POLY1305" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DHAVE_POLY1305" + AM_CFLAGS="$AM_CFLAGS -DHAVE_POLY1305 -DHAVE_ONE_TIME_AUTH" fi AM_CONDITIONAL([BUILD_POLY1305], [test "x$ENABLED_POLY1305" = "xyes"]) diff --git a/cyassl/internal.h b/cyassl/internal.h index 8dd854b52..66d4041f6 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -1556,9 +1556,6 @@ typedef struct Ciphers { #ifdef HAVE_CHACHA ChaCha* chacha; #endif -#ifdef HAVE_POLY1305 - Poly1305* poly1305; -#endif #ifdef HAVE_HC128 HC128* hc128; #endif @@ -1569,6 +1566,18 @@ typedef struct Ciphers { } Ciphers; +#ifdef HAVE_ONE_TIME_AUTH +/* Ciphers for one time authentication such as poly1305 */ +typedef struct OneTimeAuth { +#ifdef HAVE_POLY1305 + Poly1305* poly1305; +#endif + byte setup; /* flag for if a cipher has been set */ + +} OneTimeAuth; +#endif + + CYASSL_LOCAL void InitCiphers(CYASSL* ssl); CYASSL_LOCAL void FreeCiphers(CYASSL* ssl); @@ -1917,6 +1926,9 @@ struct CYASSL { Suites* suites; /* only need during handshake */ Ciphers encrypt; Ciphers decrypt; +#ifdef HAVE_ONE_TIME_AUTH + OneTimeAuth auth; +#endif CipherSpecs specs; Keys keys; int rfd; /* read file descriptor */ diff --git a/src/internal.c b/src/internal.c index 29e830130..0e00b2583 100644 --- a/src/internal.c +++ b/src/internal.c @@ -536,11 +536,13 @@ void InitCiphers(CYASSL* ssl) ssl->decrypt.chacha = NULL; #endif #ifdef HAVE_POLY1305 - ssl->encrypt.poly1305 = NULL; - ssl->decrypt.poly1305 = NULL; + ssl->auth.poly1305 = NULL; #endif ssl->encrypt.setup = 0; ssl->decrypt.setup = 0; +#ifdef HAVE_ONE_TIME_AUTH + ssl->auth.setup = 0; +#endif } @@ -595,8 +597,7 @@ void FreeCiphers(CYASSL* ssl) XFREE(ssl->decrypt.chacha, ssl->heap, DYNAMIC_TYPE_CIPHER); #endif #ifdef HAVE_POLY1305 - XFREE(ssl->encrypt.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER); - XFREE(ssl->decrypt.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER); + XFREE(ssl->auth.poly1305, ssl->heap, DYNAMIC_TYPE_CIPHER); #endif } @@ -4836,16 +4837,16 @@ static int Poly1305Tag(CYASSL* ssl, byte* additional, const byte* out, XMEMSET(padding, 0, sizeof(padding)); - if ((ret = Poly1305SetKey(ssl->encrypt.poly1305, cipher, keySz)) != 0) + if ((ret = Poly1305SetKey(ssl->auth.poly1305, cipher, keySz)) != 0) return ret; /* additional input to poly1305 */ - if ((ret = Poly1305Update(ssl->encrypt.poly1305, additional, + if ((ret = Poly1305Update(ssl->auth.poly1305, additional, CHACHA20_BLOCK_SIZE)) != 0) return ret; /* cipher input */ - if ((ret = Poly1305Update(ssl->encrypt.poly1305, out, msglen)) != 0) + if ((ret = Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0) return ret; /* handle padding for cipher input to make it 16 bytes long */ @@ -4854,7 +4855,7 @@ static int Poly1305Tag(CYASSL* ssl, byte* additional, const byte* out, if (paddingSz < 0) return INPUT_CASE_ERROR; - if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding, paddingSz)) + if ((ret = Poly1305Update(ssl->auth.poly1305, padding, paddingSz)) != 0) return ret; } @@ -4868,12 +4869,12 @@ static int Poly1305Tag(CYASSL* ssl, byte* additional, const byte* out, padding[9] = (msglen >> 8) & 0xff; padding[10] = (msglen >>16) & 0xff; padding[11] = (msglen >>24) & 0xff; - if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding, sizeof(padding))) + if ((ret = Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding))) != 0) return ret; /* generate tag */ - if ((ret = Poly1305Final(ssl->encrypt.poly1305, tag)) != 0) + if ((ret = Poly1305Final(ssl->auth.poly1305, tag)) != 0) return ret; return ret; @@ -4896,27 +4897,27 @@ static int Poly1305TagOld(CYASSL* ssl, byte* additional, const byte* out, if (msglen < 0) return INPUT_CASE_ERROR; - if ((ret = Poly1305SetKey(ssl->encrypt.poly1305, cipher, keySz)) != 0) + if ((ret = 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 = Poly1305Update(ssl->encrypt.poly1305, additional, + if ((ret = Poly1305Update(ssl->auth.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, + if ((ret = Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding))) != 0) return ret; /* add cipher info and then its length */ XMEMSET(padding, 0, sizeof(padding)); - if ((ret = Poly1305Update(ssl->encrypt.poly1305, out, msglen)) != 0) + if ((ret = Poly1305Update(ssl->auth.poly1305, out, msglen)) != 0) return ret; /* 32 bit size of cipher to 64 bit endian */ @@ -4924,12 +4925,12 @@ static int Poly1305TagOld(CYASSL* ssl, byte* additional, const byte* out, padding[1] = (msglen >> 8) & 0xff; padding[2] = (msglen >> 16) & 0xff; padding[3] = (msglen >> 24) & 0xff; - if ((ret = Poly1305Update(ssl->encrypt.poly1305, padding, sizeof(padding))) + if ((ret = Poly1305Update(ssl->auth.poly1305, padding, sizeof(padding))) != 0) return ret; /* generate tag */ - if ((ret = Poly1305Final(ssl->encrypt.poly1305, tag)) != 0) + if ((ret = Poly1305Final(ssl->auth.poly1305, tag)) != 0) return ret; return ret; diff --git a/src/keys.c b/src/keys.c index 692f3404b..628f131b0 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1849,24 +1849,13 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, } #endif -#ifdef HAVE_POLY1305 - /* set up memory space for poly1305 */ - if (enc && enc->poly1305 == NULL) - enc->poly1305 = (Poly1305*)malloc(sizeof(Poly1305)); - if (enc && enc->poly1305 == NULL) - return MEMORY_E; - if (dec && dec->poly1305 == NULL) - dec->poly1305 = - (Poly1305*)XMALLOC(sizeof(Poly1305), heap, DYNAMIC_TYPE_CIPHER); - if (dec && dec->poly1305 == NULL) - return MEMORY_E; -#endif #ifdef HAVE_CHACHA if (specs->bulk_cipher_algorithm == cyassl_chacha) { int chachaRet; if (enc && enc->chacha == NULL) - enc->chacha = (ChaCha*)malloc(sizeof(ChaCha)); + enc->chacha = + (ChaCha*)XMALLOC(sizeof(ChaCha), heap, DYNAMIC_TYPE_CIPHER); if (enc && enc->chacha == NULL) return MEMORY_E; if (dec && dec->chacha == NULL) @@ -2279,6 +2268,31 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, } +#ifdef HAVE_ONE_TIME_AUTH +/* set one time authentication keys */ +static int SetAuthKeys(OneTimeAuth* authentication, Keys* keys, + CipherSpecs* specs, void* heap, int devId) +{ + +#ifdef HAVE_POLY1305 + /* set up memory space for poly1305 */ + if (authentication && authentication->poly1305 == NULL) + authentication->poly1305 = + (Poly1305*)XMALLOC(sizeof(Poly1305), heap, DYNAMIC_TYPE_CIPHER); + if (authentication && authentication->poly1305 == NULL) + return MEMORY_E; + authentication->setup = 1; +#endif + (void)heap; + (void)keys; + (void)specs; + (void)devId; + + return 0; +} +#endif /* HAVE_ONE_TIME_AUTH */ + + /* Set encrypt/decrypt or both sides of key setup */ int SetKeysSide(CYASSL* ssl, enum encrypt_side side) { @@ -2318,6 +2332,14 @@ int SetKeysSide(CYASSL* ssl, enum encrypt_side side) return BAD_FUNC_ARG; } +#ifdef HAVE_ONE_TIME_AUTH + if (!ssl->auth.setup) { + ret = SetAuthKeys(&ssl->auth, keys, &ssl->specs, ssl->heap, devId); + if (ret != 0) + return ret; + } +#endif + ret = SetKeys(encrypt, decrypt, keys, &ssl->specs, ssl->options.side, ssl->heap, devId);