Merge pull request #5545 from icing/evp_chacha
Add ChaCha20 as available cipher in the EVP API.
This commit is contained in:
commit
d72b401e8e
@ -1006,7 +1006,7 @@ const WOLFSSL_EVP_CIPHER* wolfSSL_quic_get_hp(WOLFSSL* ssl)
|
||||
#endif
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
case TLS_CHACHA20_POLY1305_SHA256:
|
||||
evp_cipher = wolfSSL_EVP_chacha20_poly1305();
|
||||
evp_cipher = wolfSSL_EVP_chacha20();
|
||||
break;
|
||||
#endif
|
||||
#if defined(WOLFSSL_AES_COUNTER) && defined(WOLFSSL_AES_128)
|
||||
|
10
src/ssl.c
10
src/ssl.c
@ -38918,6 +38918,11 @@ int wolfSSL_RAND_poll(void)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
case CHACHA20_TYPE:
|
||||
break;
|
||||
#endif
|
||||
|
||||
case NULL_CIPHER_TYPE :
|
||||
WOLFSSL_MSG("NULL");
|
||||
break;
|
||||
@ -39007,6 +39012,11 @@ int wolfSSL_RAND_poll(void)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
case CHACHA20_TYPE:
|
||||
break;
|
||||
#endif
|
||||
|
||||
case NULL_CIPHER_TYPE :
|
||||
WOLFSSL_MSG("NULL");
|
||||
break;
|
||||
|
63
tests/api.c
63
tests/api.c
@ -52094,6 +52094,68 @@ static int test_wolfssl_EVP_chacha20_poly1305(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_wolfssl_EVP_chacha20(void)
|
||||
{
|
||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_CHACHA)
|
||||
byte key[CHACHA_MAX_KEY_SZ];
|
||||
byte iv [WOLFSSL_EVP_CHACHA_IV_BYTES];
|
||||
byte plainText[] = {0xDE, 0xAD, 0xBE, 0xEF};
|
||||
byte cipherText[sizeof(plainText)];
|
||||
byte decryptedText[sizeof(plainText)];
|
||||
EVP_CIPHER_CTX* ctx;
|
||||
int outSz;
|
||||
|
||||
printf(testingFmt, "test_wolfssl_EVP_chacha20");
|
||||
|
||||
/* Encrypt. */
|
||||
AssertNotNull((ctx = EVP_CIPHER_CTX_new()));
|
||||
AssertIntEQ(EVP_EncryptInit_ex(ctx, EVP_chacha20(), NULL, NULL,
|
||||
NULL), WOLFSSL_SUCCESS);
|
||||
/* Any tag length must fail - not an AEAD cipher. */
|
||||
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
|
||||
16, NULL), WOLFSSL_FAILURE);
|
||||
AssertIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(EVP_EncryptUpdate(ctx, cipherText, &outSz, plainText,
|
||||
sizeof(plainText)), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(outSz, sizeof(plainText));
|
||||
AssertIntEQ(EVP_EncryptFinal_ex(ctx, cipherText, &outSz), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(outSz, 0);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
/* Decrypt. */
|
||||
AssertNotNull((ctx = EVP_CIPHER_CTX_new()));
|
||||
AssertIntEQ(EVP_DecryptInit_ex(ctx, EVP_chacha20(), NULL, NULL,
|
||||
NULL), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
|
||||
sizeof(cipherText)), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(outSz, sizeof(cipherText));
|
||||
AssertIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz),
|
||||
WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(outSz, 0);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
/* Test partial Inits. CipherInit() allow setting of key and iv
|
||||
* in separate calls. */
|
||||
AssertNotNull((ctx = EVP_CIPHER_CTX_new()));
|
||||
AssertIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_chacha20(),
|
||||
key, NULL, 1), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 1),
|
||||
WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
|
||||
sizeof(cipherText)), WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(outSz, sizeof(cipherText));
|
||||
AssertIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz),
|
||||
WOLFSSL_SUCCESS);
|
||||
AssertIntEQ(outSz, 0);
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
printf(resultFmt, passed);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_wolfSSL_EVP_PKEY_hkdf(void)
|
||||
{
|
||||
#if defined(OPENSSL_EXTRA) && defined(HAVE_HKDF)
|
||||
@ -57991,6 +58053,7 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_wolfssl_EVP_aes_gcm_AAD_2_parts),
|
||||
TEST_DECL(test_wolfssl_EVP_aes_gcm),
|
||||
TEST_DECL(test_wolfssl_EVP_chacha20_poly1305),
|
||||
TEST_DECL(test_wolfssl_EVP_chacha20),
|
||||
TEST_DECL(test_wolfSSL_EVP_PKEY_hkdf),
|
||||
TEST_DECL(test_wolfSSL_PKEY_up_ref),
|
||||
TEST_DECL(test_wolfSSL_EVP_Cipher_extra),
|
||||
|
@ -166,6 +166,10 @@
|
||||
static const char EVP_CHACHA20_POLY1305[] = "CHACHA20-POLY1305";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
static const char EVP_CHACHA20[] = "CHACHA20";
|
||||
#endif
|
||||
|
||||
static const char EVP_NULL[] = "NULL";
|
||||
|
||||
#define EVP_CIPHER_TYPE_MATCHES(x, y) (XSTRCMP(x,y) == 0)
|
||||
@ -246,6 +250,9 @@ int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c)
|
||||
#endif
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
case CHACHA20_POLY1305_TYPE: return 32;
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
case CHACHA20_TYPE: return CHACHA_MAX_KEY_SZ;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
@ -702,6 +709,15 @@ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx,
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
case CHACHA20_TYPE:
|
||||
if (wc_Chacha_Process(&ctx->cipher.chacha, out, in, inl) != 0) {
|
||||
WOLFSSL_MSG("wc_ChaCha_Process failed");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
*outl = inl;
|
||||
return WOLFSSL_SUCCESS;
|
||||
#endif
|
||||
default:
|
||||
/* fall-through */
|
||||
@ -1298,6 +1314,11 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher)
|
||||
return CHACHA20_POLY1305_TYPE;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
else if (EVP_CIPHER_TYPE_MATCHES(cipher, EVP_CHACHA20))
|
||||
return CHACHA20_TYPE;
|
||||
#endif
|
||||
|
||||
else return 0;
|
||||
}
|
||||
|
||||
@ -1371,6 +1392,12 @@ int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher)
|
||||
case CHACHA20_POLY1305_TYPE:
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
case CHACHA20_TYPE:
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -1443,6 +1470,10 @@ unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher)
|
||||
case CHACHA20_POLY1305_TYPE:
|
||||
return WOLFSSL_EVP_CIPH_STREAM_CIPHER |
|
||||
WOLFSSL_EVP_CIPH_FLAG_AEAD_CIPHER;
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
case CHACHA20_TYPE:
|
||||
return WOLFSSL_EVP_CIPH_STREAM_CIPHER;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
@ -4176,6 +4207,10 @@ static const struct cipher{
|
||||
{CHACHA20_POLY1305_TYPE, EVP_CHACHA20_POLY1305, NID_chacha20_poly1305},
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
{CHACHA20_TYPE, EVP_CHACHA20, NID_chacha20},
|
||||
#endif
|
||||
|
||||
{ 0, NULL, 0}
|
||||
};
|
||||
|
||||
@ -4275,6 +4310,9 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name)
|
||||
#endif
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
{EVP_CHACHA20_POLY1305, "chacha20-poly1305"},
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
{EVP_CHACHA20, "chacha20"},
|
||||
#endif
|
||||
{ NULL, NULL}
|
||||
};
|
||||
@ -4394,6 +4432,11 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id)
|
||||
return wolfSSL_EVP_chacha20_poly1305();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
case NID_chacha20:
|
||||
return wolfSSL_EVP_chacha20();
|
||||
#endif
|
||||
|
||||
default:
|
||||
WOLFSSL_MSG("Bad cipher id value");
|
||||
}
|
||||
@ -5298,6 +5341,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_chacha20(void)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_EVP_chacha20");
|
||||
return EVP_CHACHA20;
|
||||
}
|
||||
#endif
|
||||
|
||||
const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void)
|
||||
{
|
||||
WOLFSSL_ENTER("wolfSSL_EVP_enc_null");
|
||||
@ -6652,6 +6703,39 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
if (ctx->cipherType == CHACHA20_TYPE ||
|
||||
(type && EVP_CIPHER_TYPE_MATCHES(type, EVP_CHACHA20))) {
|
||||
WOLFSSL_MSG("EVP_CHACHA20");
|
||||
ctx->cipherType = CHACHA20_TYPE;
|
||||
ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE;
|
||||
ctx->keyLen = CHACHA_MAX_KEY_SZ;
|
||||
ctx->block_size = 1;
|
||||
ctx->ivSz = WOLFSSL_EVP_CHACHA_IV_BYTES;
|
||||
if (enc == 0 || enc == 1) {
|
||||
ctx->enc = (byte) enc;
|
||||
}
|
||||
if (key != NULL && wc_Chacha_SetKey(&ctx->cipher.chacha,
|
||||
key, ctx->keyLen) != 0) {
|
||||
WOLFSSL_MSG("wc_Chacha_SetKey() failed");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
if (iv != NULL) {
|
||||
/* a bit silly. chacha takes an iv+counter and internally
|
||||
* combines them to a new iv. EVP is given exactly *one* iv,
|
||||
* so to pass it into chacha, we have to revert that first.
|
||||
* The counter comes first in little-endian */
|
||||
word32 counter = (uint32_t)iv[0] + (uint32_t)(iv[1] << 8) +
|
||||
(uint32_t)(iv[2] << 16) + (uint32_t)(iv[3] << 24);
|
||||
if (wc_Chacha_SetIV(&ctx->cipher.chacha,
|
||||
iv + sizeof(counter), counter) != 0) {
|
||||
|
||||
WOLFSSL_MSG("wc_Chacha_SetIV() failed");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_DES3
|
||||
if (ctx->cipherType == DES_CBC_TYPE ||
|
||||
(type && EVP_CIPHER_TYPE_MATCHES(type, EVP_DES_CBC))) {
|
||||
@ -8423,6 +8507,11 @@ int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx)
|
||||
WOLFSSL_MSG("CHACHA20 POLY1305");
|
||||
return CHACHA20_POLY1305_AEAD_IV_SIZE;
|
||||
#endif /* HAVE_CHACHA HAVE_POLY1305 */
|
||||
#ifdef HAVE_CHACHA
|
||||
case CHACHA20_TYPE:
|
||||
WOLFSSL_MSG("CHACHA20");
|
||||
return WOLFSSL_EVP_CHACHA_IV_BYTES;
|
||||
#endif /* HAVE_CHACHA */
|
||||
|
||||
case NULL_CIPHER_TYPE :
|
||||
WOLFSSL_MSG("NULL");
|
||||
@ -8512,6 +8601,11 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher)
|
||||
return CHACHA20_POLY1305_AEAD_IV_SIZE;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHACHA
|
||||
if (XSTRCMP(name, EVP_CHACHA20) == 0)
|
||||
return WOLFSSL_EVP_CHACHA_IV_BYTES;
|
||||
#endif
|
||||
|
||||
(void)name;
|
||||
|
||||
return 0;
|
||||
|
@ -139,6 +139,11 @@ WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc2_cbc(void);
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_chacha20_poly1305(void);
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
/* ChaCha IV + counter is set as one IV in EVP */
|
||||
#define WOLFSSL_EVP_CHACHA_IV_BYTES (CHACHA_IV_BYTES + sizeof(word32))
|
||||
WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_chacha20(void);
|
||||
#endif
|
||||
|
||||
|
||||
typedef union {
|
||||
@ -212,6 +217,9 @@ typedef union {
|
||||
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
|
||||
ChaChaPoly_Aead chachaPoly;
|
||||
#endif
|
||||
#ifdef HAVE_CHACHA
|
||||
ChaCha chacha;
|
||||
#endif
|
||||
} WOLFSSL_Cipher;
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
@ -282,7 +290,8 @@ enum {
|
||||
AES_256_OFB_TYPE = 35,
|
||||
AES_128_XTS_TYPE = 36,
|
||||
AES_256_XTS_TYPE = 37,
|
||||
CHACHA20_POLY1305_TYPE = 38
|
||||
CHACHA20_POLY1305_TYPE = 38,
|
||||
CHACHA20_TYPE = 39
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -357,7 +366,8 @@ enum {
|
||||
NID_aes_256_xts = 914,
|
||||
NID_camellia_128_cbc = 751,
|
||||
NID_camellia_256_cbc = 753,
|
||||
NID_chacha20_poly1305 = 1018
|
||||
NID_chacha20_poly1305 = 1018,
|
||||
NID_chacha20 = 1019
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -898,6 +908,7 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx,
|
||||
#define EVP_des_ede3_cbc wolfSSL_EVP_des_ede3_cbc
|
||||
#define EVP_des_ede3_ecb wolfSSL_EVP_des_ede3_ecb
|
||||
#define EVP_rc4 wolfSSL_EVP_rc4
|
||||
#define EVP_chacha20 wolfSSL_EVP_chacha20
|
||||
#define EVP_chacha20_poly1305 wolfSSL_EVP_chacha20_poly1305
|
||||
#define EVP_enc_null wolfSSL_EVP_enc_null
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user