diff --git a/src/ssl.c b/src/ssl.c index d7e39698e..8bc7c98b5 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3336,6 +3336,15 @@ static const struct cipher{ {AES_256_CBC_TYPE, "AES-256-CBC"}, #endif #if defined(OPENSSL_EXTRA) + #ifdef WOLFSSL_AES_128 + {AES_128_GCM_TYPE, "AES-128-GCM"}, + #endif + #ifdef WOLFSSL_AES_192 + {AES_192_GCM_TYPE, "AES-192-GCM"}, + #endif + #ifdef WOLFSSL_AES_256 + {AES_256_GCM_TYPE, "AES-256-GCM"}, + #endif #ifdef WOLFSSL_AES_128 {AES_128_CTR_TYPE, "AES-128-CTR"}, #endif @@ -3553,6 +3562,17 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) #endif #endif /* HAVE_AES_CBC */ #if defined(OPENSSL_EXTRA) +#ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + static char *EVP_AES_128_GCM; + #endif + #ifdef WOLFSSL_AES_192 + static char *EVP_AES_192_GCM; + #endif + #ifdef WOLFSSL_AES_256 + static char *EVP_AES_256_GCM; + #endif +#endif /* HAVE_AESGCM */ #ifdef WOLFSSL_AES_128 static char *EVP_AES_128_CTR; #endif @@ -3613,6 +3633,17 @@ void wolfSSL_EVP_init(void) #endif /* HAVE_AES_CBC */ #if defined(OPENSSL_EXTRA) + #ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + EVP_AES_128_GCM = (char *)EVP_get_cipherbyname("AES-128-GCM"); + #endif + #ifdef WOLFSSL_AES_192 + EVP_AES_192_GCM = (char *)EVP_get_cipherbyname("AES-192-GCM"); + #endif + #ifdef WOLFSSL_AES_256 + EVP_AES_256_GCM = (char *)EVP_get_cipherbyname("AES-256-GCM"); + #endif + #endif /* HAVE_AESGCM*/ #ifdef WOLFSSL_AES_128 EVP_AES_128_CTR = (char *)EVP_get_cipherbyname("AES-128-CTR"); #endif @@ -13532,6 +13563,37 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_256 */ #endif /* HAVE_AES_CBC */ + #ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_gcm(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_128_gcm"); + if (EVP_AES_128_GCM == NULL) + wolfSSL_EVP_init(); + return EVP_AES_128_GCM; + } + #endif /* WOLFSSL_GCM_128 */ + + #ifdef WOLFSSL_AES_192 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_gcm(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_192_gcm"); + if (EVP_AES_192_GCM == NULL) + wolfSSL_EVP_init(); + return EVP_AES_192_GCM; + } + #endif /* WOLFSSL_AES_192 */ + + #ifdef WOLFSSL_AES_256 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_gcm(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_256_gcm"); + if (EVP_AES_256_GCM == NULL) + wolfSSL_EVP_init(); + return EVP_AES_256_GCM; + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AESGCM */ #ifdef WOLFSSL_AES_128 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void) @@ -13714,8 +13776,6 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return 1; } - - void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx) { WOLFSSL_ENTER("EVP_CIPHER_CTX_init"); @@ -13725,7 +13785,53 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->enc = 1; /* start in encrypt mode */ } } + /* This function allows cipher specific parameters to be + determined and set. */ + int wolfSSL_EVP_CIPHER_CTX_ctrl(WOLFSSL_EVP_CIPHER_CTX *ctx, int type, \ + int arg, void *ptr) + { + int ret = WOLFSSL_FAILURE; + (void)arg; + (void)ptr; + WOLFSSL_ENTER("EVP_CIPHER_CTX_ctrl"); + + switch(type) { + case EVP_CTRL_INIT: + wolfSSL_EVP_CIPHER_CTX_init(ctx); + if(ctx) + ret = WOLFSSL_SUCCESS; + break; + case EVP_CTRL_SET_KEY_LENGTH: + ret = wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, arg); + break; + case EVP_CTRL_GCM_SET_IVLEN: + if(arg <= 0 || arg > 16) + return WOLFSSL_FAILURE; + ret = wolfSSL_EVP_CIPHER_CTX_set_iv_length(ctx, arg); + break; + case EVP_CTRL_AEAD_SET_TAG: + if(arg <= 0 || arg > 16) + return WOLFSSL_FAILURE; + + XMEMCPY(ctx->authTag, ptr, arg); + ctx->authTagSz = arg; + ret = WOLFSSL_SUCCESS; + + break; + case EVP_CTRL_AEAD_GET_TAG: + if(arg <= 0 || arg > 16) + return WOLFSSL_FAILURE; + + XMEMCPY(ptr, ctx->authTag, arg); + ret = WOLFSSL_SUCCESS; + break; + default: + WOLFSSL_MSG("EVP_CIPHER_CTX_ctrl operation not yet handled"); + ret = WOLFSSL_FAILURE; + } + return ret; + } /* WOLFSSL_SUCCESS on ok */ int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx) @@ -13862,6 +13968,102 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) } #endif /* WOLFSSL_AES_256 */ #endif /* HAVE_AES_CBC */ + #ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + if (ctx->cipherType == AES_128_GCM_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_GCM, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_128_GCM"); + ctx->cipherType = AES_128_GCM_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE; + ctx->keyLen = 16; + ctx->block_size = AES_BLOCK_SIZE; + ctx->authTagSz = AES_BLOCK_SIZE; + + XMEMSET(ctx->authTag, 0, ctx->authTagSz); + if (iv) + XMEMCPY(ctx->iv, iv, ctx->ivSz); + else + XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE); + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_128 */ + #ifdef WOLFSSL_AES_192 + if (ctx->cipherType == AES_192_GCM_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_GCM, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_192_GCM"); + ctx->cipherType = AES_192_GCM_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE; + ctx->keyLen = 24; + ctx->block_size = AES_BLOCK_SIZE; + ctx->authTagSz = AES_BLOCK_SIZE; + + XMEMSET(ctx->authTag, 0, ctx->authTagSz); + if (iv) + XMEMCPY(ctx->iv, iv, ctx->ivSz); + else + XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE); + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_192 */ + #ifdef WOLFSSL_AES_256 + if (ctx->cipherType == AES_256_GCM_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_GCM, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_256_GCM"); + ctx->cipherType = AES_256_GCM_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_GCM_MODE; + ctx->keyLen = 32; + ctx->block_size = AES_BLOCK_SIZE; + ctx->authTagSz = AES_BLOCK_SIZE; + + XMEMSET(ctx->authTag, 0, ctx->authTagSz); + if (iv) + XMEMCPY(ctx->iv, iv, ctx->ivSz); + else + XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE); + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesGcmSetKey(&ctx->cipher.aes, key, ctx->keyLen); + if (ret != 0){ + WOLFSSL_MSG("AesSetKey() failed"); + return ret; + } + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0){ + WOLFSSL_MSG("wc_AesSetIV() failed"); + return ret; + } + } + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AESGCM */ #ifdef WOLFSSL_AES_COUNTER #ifdef WOLFSSL_AES_128 if (ctx->cipherType == AES_128_CTR_TYPE || @@ -14151,7 +14353,19 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return WOLFSSL_SUCCESS; } +#if defined(HAVE_AESGCM) + int wolfSSL_EVP_CIPHER_CTX_set_iv_length(WOLFSSL_EVP_CIPHER_CTX* ctx, + int ivLen) + { + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_iv_length"); + if (ctx) + ctx->ivSz= ivLen; + else + return WOLFSSL_FAILURE; + return WOLFSSL_SUCCESS; + } +#endif /* WOLFSSL_SUCCESS on ok */ int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src, @@ -14184,6 +14398,19 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len); break; #endif /* HAVE_AES_CBC */ +#ifdef HAVE_AESGCM + case AES_128_GCM_TYPE : + case AES_192_GCM_TYPE : + case AES_256_GCM_TYPE : + WOLFSSL_MSG("AES GCM"); + if (ctx->enc) + ret = 1; + // ret = wc_AesGcmEncrypt(&ctx->cipher.aes, dst, src, len); + else + // ret = wc_AesGcmDecrypt(&ctx->cipher.aes, dst, src, len); + ret = 0; + break; +#endif /* HAVE_AESGCM */ #ifdef HAVE_AES_ECB case AES_128_ECB_TYPE : case AES_192_ECB_TYPE : @@ -14278,13 +14505,22 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) switch (ctx->cipherType) { #ifndef NO_AES +#ifdef WOLFSSL_AES_CBC case AES_128_CBC_TYPE : case AES_192_CBC_TYPE : case AES_256_CBC_TYPE : WOLFSSL_MSG("AES CBC"); XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE); break; - +#endif +#ifdef WOLFSSL_AES_GCM + case AES_128_GCM_TYPE : + case AES_192_GCM_TYPE : + case AES_256_GCM_TYPE : + WOLFSSL_MSG("AES GCM"); + XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE); + break; +#endif /* WOLFSSL_AES_GCM */ #ifdef WOLFSSL_AES_COUNTER case AES_128_CTR_TYPE : case AES_192_CTR_TYPE : @@ -14345,13 +14581,22 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) switch (ctx->cipherType) { #ifndef NO_AES +#ifdef HAVE_AES_CBC case AES_128_CBC_TYPE : case AES_192_CBC_TYPE : case AES_256_CBC_TYPE : WOLFSSL_MSG("AES CBC"); XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE); break; - +#endif +#ifdef WOLFSSL_AES_GCM + case AES_128_GCM_TYPE : + case AES_192_GCM_TYPE : + case AES_256_GCM_TYPE : + WOLFSSL_MSG("AES GCM"); + XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE); + break; +#endif #ifdef WOLFSSL_AES_COUNTER case AES_128_CTR_TYPE : case AES_192_CTR_TYPE : @@ -17485,6 +17730,24 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) } +/****************************************************************************** +* wolfSSL_ASN1_STRING_type - returns the type of +* +* RETURNS: +* returns the type set for . Otherwise, returns WOLFSSL_FAILURE. +*/ + int wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING* asn1) + { + + WOLFSSL_ENTER("wolfSSL_ASN1_STRING_type"); + + if (asn1 == NULL) { + return WOLFSSL_FAILURE; + } + + return asn1->type; + } + /* if dataSz is negative then use XSTRLEN to find length of data * return WOLFSSL_SUCCESS on success and WOLFSSL_FAILURE on failure */ int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data, @@ -18245,6 +18508,7 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) return WOLFSSL_SUCCESS; } + #endif /* XSNPRINTF */ #endif /* NO_CERTS */ @@ -22761,6 +23025,7 @@ int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...) (void)bio; (void)format; WOLFSSL_STUB("BIO_printf"); + return 0; } #endif @@ -25832,6 +26097,14 @@ int wolfSSL_RSA_public_encrypt(int len, const unsigned char* fr, hash = WC_HASH_TYPE_SHA; mgf = WC_MGF1SHA1; } + else if (padding == RSA_PKCS1_PSS_PADDING) { + padding = WC_RSA_PSS_PAD; + hash = WC_HASH_TYPE_SHA256; + mgf = WC_MGF1SHA256; + } + else if (padding == RSA_NO_PADDING) { + padding = WC_RSA_NO_PAD; + } #else if (padding == RSA_PKCS1_PADDING) ; @@ -25935,6 +26208,14 @@ int wolfSSL_RSA_private_decrypt(int len, const unsigned char* fr, hash = WC_HASH_TYPE_SHA; mgf = WC_MGF1SHA1; } + else if (padding == RSA_PKCS1_PSS_PADDING) { + padding = WC_RSA_PSS_PAD; + hash = WC_HASH_TYPE_SHA256; + mgf = WC_MGF1SHA256; + } + else if (padding == RSA_NO_PADDING) { + padding = WC_RSA_NO_PAD; + } #else if (padding == RSA_PKCS1_PADDING) ; @@ -26004,7 +26285,7 @@ int wolfSSL_RSA_private_encrypt(int len, unsigned char* in, return 0; } - if (padding != RSA_PKCS1_PADDING) { + if (padding != RSA_PKCS1_PADDING && padding != RSA_PKCS1_PSS_PADDING) { WOLFSSL_MSG("wolfSSL_RSA_private_encrypt unsupported padding"); return 0; } @@ -26689,7 +26970,7 @@ int wolfSSL_RSA_public_decrypt(int flen, const unsigned char* from, return 0; } - if (padding != RSA_PKCS1_PADDING) { + if (padding != RSA_PKCS1_PADDING && padding != RSA_PKCS1_PSS_PADDING) { WOLFSSL_MSG("wolfSSL_RSA_public_decrypt unsupported padding"); return 0; } @@ -27485,6 +27766,13 @@ int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx) WOLFSSL_MSG("AES CBC"); return AES_BLOCK_SIZE; #endif +#ifdef HAVE_AESGCM + case AES_128_GCM_TYPE : + case AES_192_GCM_TYPE : + case AES_256_GCM_TYPE : + WOLFSSL_MSG("AES GCM"); + return AES_BLOCK_SIZE; +#endif #ifdef WOLFSSL_AES_COUNTER case AES_128_CTR_TYPE : case AES_192_CTR_TYPE : @@ -27543,6 +27831,20 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher) return AES_BLOCK_SIZE; #endif #endif /* HAVE_AES_CBC */ +#ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + if (XSTRNCMP(name, EVP_AES_128_GCM, XSTRLEN(EVP_AES_128_GCM)) == 0) + return AES_BLOCK_SIZE; + #endif + #ifdef WOLFSSL_AES_192 + if (XSTRNCMP(name, EVP_AES_192_GCM, XSTRLEN(EVP_AES_192_GCM)) == 0) + return AES_BLOCK_SIZE; + #endif + #ifdef WOLFSSL_AES_256 + if (XSTRNCMP(name, EVP_AES_256_GCM, XSTRLEN(EVP_AES_256_GCM)) == 0) + return AES_BLOCK_SIZE; + #endif +#endif /* HAVE_AESGCM */ #ifdef WOLFSSL_AES_COUNTER #ifdef WOLFSSL_AES_128 if (XSTRNCMP(name, EVP_AES_128_CTR, XSTRLEN(EVP_AES_128_CTR)) == 0) @@ -30159,6 +30461,175 @@ WOLFSSL_EVP_PKEY *wolfSSL_PEM_read_PUBKEY(XFILE fp, EVP_PKEY **x, #ifndef NO_RSA +#ifdef XSNPRINTF +/* a snprintf() must be available */ + +/****************************************************************************** +* wolfSSL_RSA_print - writes the human readable form of RSA to bio +* +* RETURNS: +* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE +*/ +int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset) +{ + char tmp[100] = {0}; + word32 idx = 0; + int sz = 0; + byte lbit = 0; + int rawLen = 0; + byte* rawKey = NULL; + RsaKey* iRsa = NULL; + int i = 0; + mp_int *rsaElem = NULL; + char rsaStr[][20] = { "Modulus:", + "PublicExponent:", + "PrivateExponent:", + "Prime1:", + "Prime2:", + "Exponent1:", + "Exponent2:", + "Coefficient:" + }; + + WOLFSSL_ENTER("wolfSSL_RSA_print"); + (void)offset; + + if (bio == NULL || rsa == NULL) { + return WOLFSSL_FATAL_ERROR; + } + + if ((sz = wolfSSL_RSA_size(rsa)) < 0) { + WOLFSSL_MSG("Error getting RSA key size"); + return WOLFSSL_FAILURE; + } + iRsa = (RsaKey*)rsa->internal; + + XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s: (%d bit)", + "RSA Private-Key", 8 * sz); + tmp[sizeof(tmp) - 1] = '\0'; + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + + for (i=0; i<8; i++) { + switch(i) { + case 0: + /* Print out modulus */ + rsaElem = &iRsa->n; + break; + case 1: + rsaElem = &iRsa->e; + break; + case 2: + rsaElem = &iRsa->d; + break; + case 3: + rsaElem = &iRsa->p; + break; + case 4: + rsaElem = &iRsa->q; + break; + case 5: + rsaElem = &iRsa->dP; + break; + case 6: + rsaElem = &iRsa->dQ; + break; + case 7: + rsaElem = &iRsa->u; + break; + default: + WOLFSSL_MSG("Bad index value"); + } + + if (i == 1) { + /* Print out exponent values */ + rawLen = mp_unsigned_bin_size(rsaElem); + if (rawLen < 0) { + WOLFSSL_MSG("Error getting exponent size"); + return WOLFSSL_FAILURE; + } + + if ((word32)rawLen < sizeof(word32)) { + rawLen = sizeof(word32); + } + rawKey = (byte*)XMALLOC(rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (rawKey == NULL) { + WOLFSSL_MSG("Memory error"); + return WOLFSSL_FAILURE; + } + XMEMSET(rawKey, 0, rawLen); + mp_to_unsigned_bin(rsaElem, rawKey); + if ((word32)rawLen <= sizeof(word32)) { + idx = *(word32*)rawKey; + } + XSNPRINTF(tmp, sizeof(tmp) - 1, "\nExponent: %d (0x%x)", idx, idx); + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; + } + XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s\n ", rsaStr[i]); + tmp[sizeof(tmp) - 1] = '\0'; + if (mp_leading_bit(rsaElem)) { + lbit = 1; + XSTRNCAT(tmp, "00", 3); + } + + rawLen = mp_unsigned_bin_size(rsaElem); + rawKey = (byte*)XMALLOC(rawLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (rawKey == NULL) { + WOLFSSL_MSG("Memory error"); + return WOLFSSL_FAILURE; + } + mp_to_unsigned_bin(rsaElem, rawKey); + for (idx = 0; idx < (word32)rawLen; idx++) { + char val[5]; + int valSz = 5; + + if ((idx == 0) && !lbit) { + XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]); + } + else if ((idx != 0) && (((idx + lbit) % 15) == 0)) { + tmp[sizeof(tmp) - 1] = '\0'; + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return WOLFSSL_FAILURE; + } + XSNPRINTF(tmp, sizeof(tmp) - 1, + ":\n "); + XSNPRINTF(val, valSz - 1, "%02x", rawKey[idx]); + } + else { + XSNPRINTF(val, valSz - 1, ":%02x", rawKey[idx]); + } + XSTRNCAT(tmp, val, valSz); + } + XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + /* print out remaining values */ + if ((idx > 0) && (((idx - 1 + lbit) % 15) != 0)) { + tmp[sizeof(tmp) - 1] = '\0'; + if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { + return WOLFSSL_FAILURE; + } + } + lbit = 0; + } + + } + /* done with print out */ + if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) { + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + +#endif /* XSNPRINTF */ + #if !defined(NO_FILESYSTEM) #ifndef NO_WOLFSSL_STUB WOLFSSL_RSA *wolfSSL_PEM_read_RSAPublicKey(XFILE fp, WOLFSSL_RSA **x, diff --git a/tests/api.c b/tests/api.c index c0d22566d..b51315067 100644 --- a/tests/api.c +++ b/tests/api.c @@ -20722,6 +20722,7 @@ static void test_wolfSSL_ASN1_STRING(void) printf(testingFmt, "wolfSSL_ASN1_STRING()"); AssertNotNull(str = ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); + AssertIntEQ(ASN1_STRING_type(str), V_ASN1_OCTET_STRING); AssertIntEQ(ASN1_STRING_set(str, (const void*)data, sizeof(data)), 1); AssertIntEQ(ASN1_STRING_set(str, (const void*)data, -1), 1); AssertIntEQ(ASN1_STRING_set(str, NULL, -1), 0); @@ -23825,6 +23826,152 @@ static void test_wc_ecc_get_curve_id_from_params(void) printf(resultFmt, passed); #endif } +static void test_wolfSSL_EVP_PKEY_encrypt(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) + WOLFSSL_RSA* rsa = NULL; + WOLFSSL_EVP_PKEY* pkey = NULL; + WOLFSSL_EVP_PKEY_CTX* ctx = NULL; + const char* in = "What is easy to do is easy not to do."; + size_t inlen = XSTRLEN(in); + size_t outEncLen = 0; + byte* outEnc = NULL; + byte* outDec = NULL; + size_t outDecLen = 0; + size_t rsaKeySz = 2048/8; /* Bytes */ +#ifdef WC_RSA_NO_PADDING + byte* inTmp = NULL; + byte* outEncTmp = NULL; + byte* outDecTmp = NULL; +#endif + printf(testingFmt, "wolfSSL_EVP_PKEY_encrypt()"); + + AssertNotNull(outEnc = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER)); + XMEMSET(outEnc, 0, rsaKeySz); + AssertNotNull(outDec = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER)); + XMEMSET(outDec, 0, rsaKeySz); + + AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); + AssertNotNull(pkey = wolfSSL_PKEY_new()); + AssertIntEQ(EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS); + AssertNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL)); + AssertIntEQ(EVP_PKEY_encrypt_init(ctx), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING), + WOLFSSL_SUCCESS); + + /* Encrypt data */ + AssertIntEQ(EVP_PKEY_encrypt(ctx, outEnc, &outEncLen, + (const unsigned char*)in, inlen), WOLFSSL_SUCCESS); + /* Decrypt data */ + AssertIntEQ(EVP_PKEY_decrypt_init(ctx), WOLFSSL_SUCCESS); + + AssertIntEQ(EVP_PKEY_decrypt(ctx, outDec, &outDecLen, outEnc, outEncLen), + WOLFSSL_SUCCESS); + + AssertIntEQ(XMEMCMP(in, outDec, outDecLen), 0); + +#ifdef WC_RSA_NO_PADDING + /* The input length must be the same size as the RSA key.*/ + AssertNotNull(inTmp = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER)); + XMEMSET(inTmp, 9, rsaKeySz); + AssertNotNull(outEncTmp = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER)); + XMEMSET(outEncTmp, 0, rsaKeySz); + AssertNotNull(outDecTmp = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER)); + XMEMSET(outDecTmp, 0, rsaKeySz); + AssertIntEQ(EVP_PKEY_encrypt_init(ctx), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING), + WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_encrypt(ctx, outEncTmp, &outEncLen, inTmp, rsaKeySz), + WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_decrypt_init(ctx), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_PKEY_decrypt(ctx, outDecTmp, &outDecLen, outEncTmp, outEncLen), + WOLFSSL_SUCCESS); + AssertIntEQ(XMEMCMP(inTmp, outDecTmp, outDecLen), 0); +#endif + + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + XFREE(outEnc, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(outDec, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef WC_RSA_NO_PADDING + XFREE(inTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(outEncTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(outDecTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); +#endif + printf(resultFmt, passed); +#endif +} +static void test_wolfSSL_EVP_PKEY_sign(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) + WOLFSSL_RSA* rsa = NULL; + WOLFSSL_EVP_PKEY* pkey = NULL; + WOLFSSL_EVP_PKEY_CTX* ctx = NULL; + const char* in = "What is easy to do is easy not to do."; + size_t inlen = XSTRLEN(in); + byte hash[SHA256_DIGEST_LENGTH] = {0}; + SHA256_CTX c; + byte* sig = NULL; + byte* sigVerify = NULL; + size_t siglen = 0; + size_t rsaKeySz = 2048/8; /* Bytes */ + + printf(testingFmt, "wolfSSL_EVP_PKEY_sign()"); + + AssertNotNull(sig = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER)); + XMEMSET(sig, 0, rsaKeySz); + AssertNotNull(sigVerify = (byte*)XMALLOC(rsaKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER)); + XMEMSET(sigVerify, 0, rsaKeySz); + + /* Generate hash */ + SHA256_Init(&c); + SHA256_Update(&c, in, inlen); + SHA256_Final(hash, &c); + + AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); + AssertNotNull(pkey = wolfSSL_PKEY_new()); + AssertIntEQ(EVP_PKEY_assign_RSA(pkey, rsa), WOLFSSL_SUCCESS); + AssertNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL)); + AssertIntEQ(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS); +#ifdef WC_RSA_PSS + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), + WOLFSSL_SUCCESS); +#else + AssertIntEQ(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING), + WOLFSSL_SUCCESS); +#endif + + /* Sign data */ + AssertIntEQ(EVP_PKEY_sign(ctx, sig, &siglen, hash, SHA256_DIGEST_LENGTH), + WOLFSSL_SUCCESS); + /* Verify signature. + EVP_PKEY_verify() doesn't exist yet, so use RSA_public_decrypt(). */ +#ifdef WC_RSA_PSS + AssertIntEQ(RSA_public_decrypt(siglen, sig, sigVerify, + rsa, RSA_PKCS1_PSS_PADDING), SHA256_DIGEST_LENGTH); +#else + AssertIntEQ(RSA_public_decrypt(siglen, sig, sigVerify, + rsa, RSA_PKCS1_PADDING), SHA256_DIGEST_LENGTH); +#endif + + AssertIntEQ(XMEMCMP(hash, sigVerify, SHA256_DIGEST_LENGTH), 0); + /* error cases */ + + AssertIntNE(EVP_PKEY_sign_init(NULL), WOLFSSL_SUCCESS); + ctx->pkey->type = EVP_PKEY_RSA2; + AssertIntNE(EVP_PKEY_sign_init(ctx), WOLFSSL_SUCCESS); + AssertIntNE(EVP_PKEY_sign(NULL, sig, &siglen, (byte*)in, inlen), + WOLFSSL_SUCCESS); + AssertIntNE(EVP_PKEY_sign(ctx, sig, &siglen, (byte*)in, inlen), + WOLFSSL_SUCCESS); + + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + XFREE(sig, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(sigVerify, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + printf(resultFmt, passed); +#endif +} static void test_EVP_PKEY_rsa(void) { @@ -25127,6 +25274,87 @@ static void test_wolfSSL_PEM_read(void) #endif } + +static void test_wolfssl_EVP_aes_gcm(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) + + /* A 256 bit key, AES_128 will use the first 128 bit*/ + byte *key = (byte*)"01234567890123456789012345678901"; + /* A 128 bit IV */ + byte *iv = (byte*)"0123456789012345"; + int ivSz = AES_BLOCK_SIZE; + /* Message to be encrypted */ + byte *plaintxt = (byte*)"for things to change you have to change"; + /* Additional non-confidential data */ + byte *aad = (byte*)"Don't spend major time on minor things."; + + unsigned char tag[AES_BLOCK_SIZE] = {0}; + int plaintxtSz = XSTRLEN((char*)plaintxt); + int aadSz = XSTRLEN((char*)aad); + byte ciphertxt[AES_BLOCK_SIZE * 4] = {0}; + byte decryptedtxt[AES_BLOCK_SIZE * 4] = {0}; + int ciphertxtSz = 0; + int decryptedtxtSz = 0; + int len = 0; + EVP_CIPHER_CTX en; + EVP_CIPHER_CTX de; + + printf(testingFmt, "wolfssl_EVP_aes_gcm"); + + EVP_CIPHER_CTX_init(&en); +#ifdef WOLFSSL_AES_128 + AssertIntEQ(1, EVP_EncryptInit_ex(&en, EVP_aes_128_gcm(), NULL, NULL, NULL)); +#elif defined(WOLFSSL_AES_192) + AssertIntEQ(1, EVP_EncryptInit_ex(&en, EVP_aes_192_gcm(), NULL, NULL, NULL)); +#elif defined(WOLFSSL_AES_256) + AssertIntEQ(1, EVP_EncryptInit_ex(&en, EVP_aes_256_gcm(), NULL, NULL, NULL)); +#endif + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_EncryptInit_ex(&en, NULL, NULL, key, iv)); + AssertIntEQ(1, EVP_EncryptUpdate(&en, NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_EncryptUpdate(&en, ciphertxt, &len, plaintxt, plaintxtSz)); + ciphertxtSz = len; + AssertIntEQ(1, EVP_EncryptFinal_ex(&en, ciphertxt, &len)); + ciphertxtSz += len; + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&en, EVP_CTRL_GCM_GET_TAG, AES_BLOCK_SIZE, tag)); + + EVP_CIPHER_CTX_init(&de); +#ifdef WOLFSSL_AES_128 + AssertIntEQ(1, EVP_EncryptInit_ex(&de, EVP_aes_128_gcm(), NULL, NULL, NULL)); +#elif defined(WOLFSSL_AES_192) + AssertIntEQ(1, EVP_EncryptInit_ex(&de, EVP_aes_192_gcm(), NULL, NULL, NULL)); +#elif defined(WOLFSSL_AES_256) + AssertIntEQ(1, EVP_EncryptInit_ex(&de, EVP_aes_256_gcm(), NULL, NULL, NULL)); +#endif + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_EncryptInit_ex(&de, NULL, NULL, key, iv)); + AssertIntEQ(1, EVP_EncryptUpdate(&de, NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de, EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag)); + AssertIntEQ(1, EVP_DecryptUpdate(&de, decryptedtxt, &len, ciphertxt, ciphertxtSz)); + decryptedtxtSz = len; + AssertIntGT(EVP_DecryptFinal_ex(&de, decryptedtxt, &len), 0); + decryptedtxtSz += len; + AssertIntEQ(ciphertxtSz, decryptedtxtSz); + AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + /* modify tag*/ + tag[AES_BLOCK_SIZE-1]+=0xBB; + AssertIntEQ(1, EVP_EncryptUpdate(&de, NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de, EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag)); + AssertIntEQ(1, EVP_DecryptUpdate(&de, decryptedtxt, &len, ciphertxt, ciphertxtSz)); + decryptedtxtSz = len; + AssertIntGT(EVP_DecryptFinal_ex(&de, decryptedtxt, &len), 0); + decryptedtxtSz += len; + AssertIntEQ(ciphertxtSz, decryptedtxtSz); + /* decrypted text should not be equal to plain text*/ + AssertIntNE(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + printf(resultFmt, passed); + +#endif /* OPENSSL_EXTRA && !NO_AES && HAVE_AESGCM */ +} + static void test_wolfSSL_X509_NAME_ENTRY_get_object() { #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) @@ -25384,7 +25612,25 @@ static void test_wolfSSL_X509_print() printf(resultFmt, passed); #endif } +static void test_wolfSSL_RSA_print() +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \ + !defined(NO_RSA) && !defined(HAVE_FAST_RSA) + BIO *bio; + WOLFSSL_RSA* rsa = NULL; + printf(testingFmt, "wolfSSL_RSA_print"); + + AssertNotNull(rsa = RSA_generate_key(2048, 3, NULL, NULL)); + AssertNotNull(bio = wolfSSL_BIO_new(wolfSSL_BIO_s_file())); + wolfSSL_BIO_set_fp(bio, stdout, BIO_NOCLOSE); + AssertIntEQ(RSA_print(bio, rsa, 0), SSL_SUCCESS); + + BIO_free(bio); + wolfSSL_RSA_free(rsa); + printf(resultFmt, passed); +#endif +} static void test_wolfSSL_RSA_verify() { #if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) && \ @@ -25707,6 +25953,7 @@ void ApiTest(void) test_wolfSSL_DC_cert(); test_wolfSSL_DES_ncbc(); test_wolfSSL_AES_cbc_encrypt(); + test_wolfssl_EVP_aes_gcm(); #if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA) AssertIntEQ(test_wolfSSL_CTX_use_certificate_ASN1(), WOLFSSL_SUCCESS); @@ -25717,15 +25964,17 @@ void ApiTest(void) test_wolfSSL_X509_get_version(); test_wolfSSL_X509_print(); test_wolfSSL_RSA_verify(); - test_wolfSSL_X509_get_ext_count(); test_wolfSSL_X509_cmp(); + test_wolfSSL_RSA_print(); /* test the no op functions for compatibility */ test_no_op_functions(); /* OpenSSL EVP_PKEY API tests */ test_EVP_PKEY_rsa(); + test_wolfSSL_EVP_PKEY_encrypt(); + test_wolfSSL_EVP_PKEY_sign(); test_EVP_PKEY_ec(); /* OpenSSL error API tests */ test_ERR_load_crypto_strings(); diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 365e4cf2b..0c7b47793 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2569,7 +2569,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv) #else /* STD_PERI_LIB */ int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) { - int ret; + int ret; word32 *iv; word32 blocks = (sz / AES_BLOCK_SIZE); CRYP_InitTypeDef cryptInit; @@ -2638,7 +2638,7 @@ int wc_AesSetIV(Aes* aes, const byte* iv) #ifdef HAVE_AES_DECRYPT int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) { - int ret; + int ret; word32 *iv; word32 blocks = (sz / AES_BLOCK_SIZE); CRYP_InitTypeDef cryptInit; @@ -5121,6 +5121,11 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, x[1] ^= bigA[1]; GMULT(x, bigH); } +#ifdef OPENSSL_EXTRA + /* store AAD partial tag for next call */ + aes->aadH[0] = x[0]; + aes->aadH[1] = x[1]; +#endif } /* Hash in C, the Ciphertext */ @@ -5128,6 +5133,13 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, word64 bigC[2]; blocks = cSz / AES_BLOCK_SIZE; partial = cSz % AES_BLOCK_SIZE; +#ifdef OPENSSL_EXTRA + /* Start from last AAD partial tag */ + if(aes->aadLen) { + x[0] = aes->aadH[0]; + x[1] = aes->aadH[1]; + } +#endif while (blocks--) { XMEMCPY(bigC, c, AES_BLOCK_SIZE); #ifdef LITTLE_ENDIAN_ORDER @@ -5154,7 +5166,10 @@ void GHASH(Aes* aes, const byte* a, word32 aSz, const byte* c, { word64 len[2]; len[0] = aSz; len[1] = cSz; - +#ifdef OPENSSL_EXTRA + if (aes->aadLen) + len[0] = aes->aadLen; +#endif /* Lengths are in bytes. Convert to bits. */ len[0] *= 8; len[1] *= 8; @@ -5514,7 +5529,7 @@ static int wc_AesGcmEncrypt_STM32(Aes* aes, byte* out, const byte* in, word32 sz xorbuf(authTag, tag, authTagSz); } else { - XMEMCPY(authTag, tag, authTagSz); + XMEMCPY(authTag, tag, authTagSz); } } } @@ -5551,7 +5566,9 @@ int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz, byte initialCounter[AES_BLOCK_SIZE]; byte *ctr; byte scratch[AES_BLOCK_SIZE]; - +#ifdef OPENSSL_EXTRA + word64 aadTemp; +#endif ctr = counter; XMEMSET(initialCounter, 0, AES_BLOCK_SIZE); if (ivSz == GCM_NONCE_MID_SZ) { @@ -5559,7 +5576,14 @@ int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz, initialCounter[AES_BLOCK_SIZE - 1] = 1; } else { +#ifdef OPENSSL_EXTRA + aadTemp = aes->aadLen; + aes->aadLen = 0; +#endif GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); +#ifdef OPENSSL_EXTRA + aes->aadLen = aadTemp; +#endif } XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE); @@ -5614,11 +5638,15 @@ int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz, xorbuf(scratch, p, partial); XMEMCPY(c, scratch, partial); } - if (authTag) { GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); wc_AesEncrypt(aes, initialCounter, scratch); xorbuf(authTag, scratch, authTagSz); +#ifdef OPENSSL_EXTRA + if (!in && !sz) + /* store AAD size for next call */ + aes->aadLen = authInSz; +#endif } return ret; @@ -5966,7 +5994,9 @@ int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz, byte scratch[AES_BLOCK_SIZE]; byte Tprime[AES_BLOCK_SIZE]; byte EKY0[AES_BLOCK_SIZE]; - +#ifdef OPENSSL_EXTRA + word64 aadTemp; +#endif ctr = counter; XMEMSET(initialCounter, 0, AES_BLOCK_SIZE); if (ivSz == GCM_NONCE_MID_SZ) { @@ -5974,7 +6004,14 @@ int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz, initialCounter[AES_BLOCK_SIZE - 1] = 1; } else { +#ifdef OPENSSL_EXTRA + aadTemp = aes->aadLen; + aes->aadLen = 0; +#endif GHASH(aes, NULL, 0, iv, ivSz, initialCounter, AES_BLOCK_SIZE); +#ifdef OPENSSL_EXTRA + aes->aadLen = aadTemp; +#endif } XMEMCPY(ctr, initialCounter, AES_BLOCK_SIZE); @@ -5983,6 +6020,13 @@ int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz, wc_AesEncrypt(aes, ctr, EKY0); xorbuf(Tprime, EKY0, sizeof(Tprime)); +#ifdef OPENSSL_EXTRA + if (!out) { + /* authenticated, non-confidential data */ + /* store AAD size for next call */ + aes->aadLen = authInSz; + } +#endif if (ConstantCompare(authTag, Tprime, authTagSz) != 0) { return AES_GCM_AUTH_E; } @@ -6774,6 +6818,12 @@ int wc_AesInit(Aes* aes, void* heap, int devId) #endif #if defined(WOLFSSL_CRYPTOCELL) && defined(WOLFSSL_CRYPTOCELL_AES) XMEMSET(&aes->ctx, 0, sizeof(aes->ctx)); +#endif +#ifdef HAVE_AESGCM +#ifdef OPENSSL_EXTRA + XMEMSET(aes->aadH, 0, sizeof(aes->aadH)); + aes->aadLen = 0; +#endif #endif return ret; } diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 277fae844..e751196ef 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -48,21 +48,28 @@ int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c) } switch (cipherType(c)) { - #if !defined(NO_AES) && defined(HAVE_AES_CBC) +#if !defined(NO_AES) + #if defined(HAVE_AES_CBC) case AES_128_CBC_TYPE: return 16; case AES_192_CBC_TYPE: return 24; case AES_256_CBC_TYPE: return 32; #endif - #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + #if defined(HAVE_AESGCM) + case AES_128_GCM_TYPE: return 16; + case AES_192_GCM_TYPE: return 24; + case AES_256_GCM_TYPE: return 32; + #endif + #if defined(WOLFSSL_AES_COUNTER) case AES_128_CTR_TYPE: return 16; case AES_192_CTR_TYPE: return 24; case AES_256_CTR_TYPE: return 32; #endif - #if !defined(NO_AES) && defined(HAVE_AES_ECB) + #if defined(HAVE_AES_ECB) case AES_128_ECB_TYPE: return 16; case AES_192_ECB_TYPE: return 24; case AES_256_ECB_TYPE: return 32; #endif +#endif /* !NO_AES */ #ifndef NO_DES3 case DES_CBC_TYPE: return 8; case DES_EDE3_CBC_TYPE: return 24; @@ -238,7 +245,8 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, int ret = 0; switch (ctx->cipherType) { - #if !defined(NO_AES) && defined(HAVE_AES_CBC) +#if !defined(NO_AES) + #if defined(HAVE_AES_CBC) case AES_128_CBC_TYPE: case AES_192_CBC_TYPE: case AES_256_CBC_TYPE: @@ -248,14 +256,55 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, ret = wc_AesCbcDecrypt(&ctx->cipher.aes, out, in, inl); break; #endif - #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + #if defined(HAVE_AESGCM) + case AES_128_GCM_TYPE: + case AES_192_GCM_TYPE: + case AES_256_GCM_TYPE: + if (ctx->enc) { + if (out){ + /* encrypt confidential data*/ + ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out, in, inl, + ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, + NULL, 0); + } + else { + /* authenticated, non-confidential data */ + ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL, NULL, 0, + ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, + in, inl); + /* Reset partial authTag error for AAD*/ + if (ret == AES_GCM_AUTH_E) + ret = 0; + } + } + else { + if (out){ + /* decrypt confidential data*/ + ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out, in, inl, + ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, + NULL, 0); + } + else { + /* authenticated, non-confidential data*/ + ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0, + ctx->iv, ctx->ivSz, + ctx->authTag, ctx->authTagSz, + in, inl); + /* Reset partial authTag error for AAD*/ + if (ret == AES_GCM_AUTH_E) + ret = 0; + } + } + break; + #endif + #if defined(WOLFSSL_AES_COUNTER) case AES_128_CTR_TYPE: case AES_192_CTR_TYPE: case AES_256_CTR_TYPE: ret = wc_AesCtrEncrypt(&ctx->cipher.aes, out, in, inl); break; #endif - #if !defined(NO_AES) && defined(HAVE_AES_ECB) + #if defined(HAVE_AES_ECB) case AES_128_ECB_TYPE: case AES_192_ECB_TYPE: case AES_256_ECB_TYPE: @@ -265,6 +314,7 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, ret = wc_AesEcbDecrypt(&ctx->cipher.aes, out, in, inl); break; #endif +#endif /* !NO_AES */ #ifndef NO_DES3 case DES_CBC_TYPE: if (ctx->enc) @@ -306,6 +356,16 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, return WOLFSSL_SUCCESS; /* success */ } +static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx, + unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + /* process blocks */ + if (evpCipherBlock(ctx, out, in, inl) == 0) + return WOLFSSL_FAILURE; + *outl = inl; + return WOLFSSL_SUCCESS; +} WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) @@ -314,12 +374,30 @@ WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, int fill; if ((ctx == NULL) || (inl < 0) || - (outl == NULL)|| (out == NULL) || (in == NULL)) return BAD_FUNC_ARG; + (outl == NULL)|| (in == NULL)) return BAD_FUNC_ARG; WOLFSSL_ENTER("wolfSSL_EVP_CipherUpdate"); *outl = 0; if (inl == 0) return WOLFSSL_SUCCESS; +#if defined(HAVE_AESGCM) + switch (ctx->cipherType) { +#if !defined(NO_AES) + #if defined(HAVE_AESGCM) + case AES_128_GCM_TYPE: + case AES_192_GCM_TYPE: + case AES_256_GCM_TYPE: +/* if out == NULL, in/inl contains the additional authenticated data for GCM */ + return wolfSSL_EVP_CipherUpdate_GCM(ctx, out, outl, in, inl); + #endif + default: + /* fall-through*/ + if (out == NULL) + return BAD_FUNC_ARG; + } +#endif /* !NO_AES */ +#endif /* HAVE_AESGCM */ + if (ctx->bufUsed > 0) { /* concatinate them if there is anything */ fill = fillBuff(ctx, in, inl); inl -= fill; @@ -414,11 +492,30 @@ WOLFSSL_API int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, return BAD_FUNC_ARG; WOLFSSL_ENTER("wolfSSL_EVP_CipherFinal"); - if (ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) { - if (ctx->bufUsed != 0) return WOLFSSL_FAILURE; - *outl = 0; - return WOLFSSL_SUCCESS; - } + +#if defined(HAVE_AESGCM) + switch (ctx->cipherType) { +#if !defined(NO_AES) + #if defined(HAVE_AESGCM) + case AES_128_GCM_TYPE: + case AES_192_GCM_TYPE: + case AES_256_GCM_TYPE: + *outl = 0; + /* Clear IV, since IV reuse is not recommended for AES GCM. */ + XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE); + return WOLFSSL_SUCCESS; + #endif + default: + /* fall-through*/ + if (ctx->flags & WOLFSSL_EVP_CIPH_NO_PADDING) { + if (ctx->bufUsed != 0) return WOLFSSL_FAILURE; + *outl = 0; + return WOLFSSL_SUCCESS; + } + } +#endif /* !NO_AES */ +#endif /* HAVE_AESGCM */ + if (ctx->enc) { if (ctx->block_size == 1) { *outl = 0; @@ -517,21 +614,27 @@ WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX * if (ctx == NULL) return BAD_FUNC_ARG; switch (ctx->cipherType) { #if !defined(NO_AES) || !defined(NO_DES3) -#if !defined(NO_AES) && defined(HAVE_AES_CBC) +#if !defined(NO_AES) +#if defined(HAVE_AES_CBC) case AES_128_CBC_TYPE: case AES_192_CBC_TYPE: case AES_256_CBC_TYPE: #endif -#if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) +#if defined(HAVE_AESGCM) + case AES_128_GCM_TYPE: + case AES_192_GCM_TYPE: + case AES_256_GCM_TYPE: +#endif +#if defined(WOLFSSL_AES_COUNTER) case AES_128_CTR_TYPE: case AES_192_CTR_TYPE: case AES_256_CTR_TYPE: #endif -#if !defined(NO_AES) + case AES_128_ECB_TYPE: case AES_192_ECB_TYPE: case AES_256_ECB_TYPE: -#endif +#endif /* !NO_AES */ #ifndef NO_DES3 case DES_CBC_TYPE: case DES_ECB_TYPE: @@ -560,8 +663,8 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) return DES_EDE3_ECB_TYPE; #endif /* NO_DES3 && HAVE_AES_ECB */ #endif - - #if !defined(NO_AES) && defined(HAVE_AES_CBC) + #if !defined(NO_AES) + #if defined(HAVE_AES_CBC) #ifdef WOLFSSL_AES_128 else if (XSTRNCMP(cipher, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) return AES_128_CBC_TYPE; @@ -574,8 +677,22 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) else if (XSTRNCMP(cipher, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) return AES_256_CBC_TYPE; #endif - #endif /* !NO_AES && HAVE_AES_CBC */ - #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + #endif /* HAVE_AES_CBC */ + #if defined(HAVE_AESGCM) + #ifdef WOLFSSL_AES_128 + else if (XSTRNCMP(cipher, EVP_AES_128_GCM, EVP_AES_SIZE) == 0) + return AES_128_GCM_TYPE; + #endif + #ifdef WOLFSSL_AES_192 + else if (XSTRNCMP(cipher, EVP_AES_192_GCM, EVP_AES_SIZE) == 0) + return AES_192_GCM_TYPE; + #endif + #ifdef WOLFSSL_AES_256 + else if (XSTRNCMP(cipher, EVP_AES_256_GCM, EVP_AES_SIZE) == 0) + return AES_256_GCM_TYPE; + #endif + #endif /* HAVE_AESGCM */ + #if defined(WOLFSSL_AES_COUNTER) #ifdef WOLFSSL_AES_128 else if (XSTRNCMP(cipher, EVP_AES_128_CTR, EVP_AES_SIZE) == 0) return AES_128_CTR_TYPE; @@ -588,8 +705,8 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) else if (XSTRNCMP(cipher, EVP_AES_256_CTR, EVP_AES_SIZE) == 0) return AES_256_CTR_TYPE; #endif - #endif /* !NO_AES && HAVE_AES_CBC */ - #if !defined(NO_AES) && defined(HAVE_AES_ECB) + #endif /* HAVE_AES_CBC */ + #if defined(HAVE_AES_ECB) #ifdef WOLFSSL_AES_128 else if (XSTRNCMP(cipher, EVP_AES_128_ECB, EVP_AES_SIZE) == 0) return AES_128_ECB_TYPE; @@ -602,7 +719,8 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) else if (XSTRNCMP(cipher, EVP_AES_256_ECB, EVP_AES_SIZE) == 0) return AES_256_ECB_TYPE; #endif - #endif /* !NO_AES && HAVE_AES_CBC */ + #endif /*HAVE_AES_CBC */ +#endif /* !NO_AES */ else return 0; } @@ -610,24 +728,32 @@ WOLFSSL_API int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher) { if (cipher == NULL) return BAD_FUNC_ARG; switch (cipherType(cipher)) { - #if !defined(NO_AES) && defined(HAVE_AES_CBC) +#if !defined(NO_AES) + #if defined(HAVE_AES_CBC) case AES_128_CBC_TYPE: case AES_192_CBC_TYPE: case AES_256_CBC_TYPE: - return AES_BLOCK_SIZE; + return AES_BLOCK_SIZE; #endif - #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + #if defined(HAVE_AESGCM) + case AES_128_GCM_TYPE: + case AES_192_GCM_TYPE: + case AES_256_GCM_TYPE: + return AES_BLOCK_SIZE; + #endif + #if defined(WOLFSSL_AES_COUNTER) case AES_128_CTR_TYPE: case AES_192_CTR_TYPE: case AES_256_CTR_TYPE: - return AES_BLOCK_SIZE; + return AES_BLOCK_SIZE; #endif - #if !defined(NO_AES) && defined(HAVE_AES_ECB) + #if defined(HAVE_AES_ECB) case AES_128_ECB_TYPE: case AES_192_ECB_TYPE: case AES_256_ECB_TYPE: - return AES_BLOCK_SIZE; + return AES_BLOCK_SIZE; #endif +#endif /* NO_AES */ #ifndef NO_DES3 case DES_CBC_TYPE: return 8; case DES_EDE3_CBC_TYPE: return 8; @@ -642,24 +768,30 @@ WOLFSSL_API int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher) unsigned long WOLFSSL_CIPHER_mode(const WOLFSSL_EVP_CIPHER *cipher) { switch (cipherType(cipher)) { - #if !defined(NO_AES) && defined(HAVE_AES_CBC) +#if !defined(NO_AES) + #if defined(HAVE_AES_CBC) case AES_128_CBC_TYPE: case AES_192_CBC_TYPE: case AES_256_CBC_TYPE: return WOLFSSL_EVP_CIPH_CBC_MODE; #endif - #if !defined(NO_AES) && defined(WOLFSSL_AES_COUNTER) + #if defined(WOLFSSL_AES_GCM) + case AES_128_GCM_TYPE: + case AES_192_GCM_TYPE: + case AES_256_GCM_TYPE: + return WOLFSSL_EVP_CIPH_GCM_MODE; + #endif + #if defined(WOLFSSL_AES_COUNTER) case AES_128_CTR_TYPE: case AES_192_CTR_TYPE: case AES_256_CTR_TYPE: return WOLFSSL_EVP_CIPH_CTR_MODE; #endif - #if !defined(NO_AES) case AES_128_ECB_TYPE: case AES_192_ECB_TYPE: case AES_256_ECB_TYPE: return WOLFSSL_EVP_CIPH_ECB_MODE; - #endif +#endif /* NO_ASE */ #ifndef NO_DES3 case DES_CBC_TYPE: case DES_EDE3_CBC_TYPE: @@ -921,7 +1053,77 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_encrypt_init(WOLFSSL_EVP_PKEY_CTX *ctx) } return WOLFSSL_FAILURE; } +/****************************************************************************** +* wolfSSL_EVP_PKEY_sign_init - initializes a public key algorithm context for +* a signing operation. +* +* RETURNS: +* returns WOLFSSL_SUCCESS on success, otherwise returns -2 +*/ +WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx) +{ + WOLFSSL_MSG("wolfSSL_EVP_PKEY_sign_init"); + if (!ctx || !ctx->pkey) + return -2; + + switch (ctx->pkey->type) { + case EVP_PKEY_RSA: + ctx->op = EVP_PKEY_OP_SIGN; + return WOLFSSL_SUCCESS; + case EVP_PKEY_EC: + WOLFSSL_MSG("not implemented"); + FALL_THROUGH; + default: + return -2; + } + return WOLFSSL_SUCCESS; +} +/****************************************************************************** +* wolfSSL_EVP_PKEY_sign - performs a public key signing operation using ctx +* The data to be signed should be hashed since the function does not hash the data. +* +* RETURNS: +* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE +*/ + +WOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, size_t tbslen) +{ + int len = 0; + + WOLFSSL_MSG("wolfSSL_EVP_PKEY_sign"); + + if (!ctx || ctx->op != EVP_PKEY_OP_SIGN || !ctx->pkey) + return WOLFSSL_FAILURE; + + (void)sig; + (void)siglen; + (void)tbs; + (void)tbslen; + (void)len; + + switch (ctx->pkey->type) { +#if !defined(NO_RSA) && !defined(HAVE_USER_RSA) + case EVP_PKEY_RSA: + len = wolfSSL_RSA_private_encrypt((int)tbslen, (unsigned char*)tbs, sig, + ctx->pkey->rsa, ctx->padding); + if (len < 0) + break; + else { + *siglen = len; + return WOLFSSL_SUCCESS; + } +#endif /* NO_RSA */ + + case EVP_PKEY_EC: + WOLFSSL_MSG("not implemented"); + FALL_THROUGH; + default: + break; + } + return WOLFSSL_FAILURE; +} /* Get the size in bits for WOLFSSL_EVP_PKEY key * diff --git a/wolfssl/openssl/asn1.h b/wolfssl/openssl/asn1.h index 4c8286579..6500f6cd1 100644 --- a/wolfssl/openssl/asn1.h +++ b/wolfssl/openssl/asn1.h @@ -28,6 +28,7 @@ #define ASN1_STRING_new wolfSSL_ASN1_STRING_type_new #define ASN1_STRING_type_new wolfSSL_ASN1_STRING_type_new +#define ASN1_STRING_type wolfSSL_ASN1_STRING_type #define ASN1_STRING_set wolfSSL_ASN1_STRING_set #define ASN1_STRING_free wolfSSL_ASN1_STRING_free diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 89dc981a5..62c8d24fa 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -93,6 +93,11 @@ WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void); #endif +#if !defined(NO_AES) && defined(HAVE_AESGCM) +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_gcm(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_gcm(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_gcm(void); +#endif WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void); @@ -177,6 +182,9 @@ enum { #ifdef HAVE_IDEA IDEA_CBC_TYPE = 19, #endif + AES_128_GCM_TYPE = 21, + AES_192_GCM_TYPE = 22, + AES_256_GCM_TYPE = 23, NID_sha1 = 64, NID_sha224 = 65, NID_md2 = 77, @@ -189,6 +197,9 @@ enum { NID_aes_128_cbc = 419, NID_aes_192_cbc = 423, NID_aes_256_cbc = 427, + NID_aes_128_gcm = 895, + NID_aes_192_gcm = 898, + NID_aes_256_gcm = 901, NID_aes_128_ctr = 904, NID_aes_192_ctr = 905, NID_aes_256_ctr = 906, @@ -221,6 +232,11 @@ typedef struct WOLFSSL_EVP_CIPHER_CTX { int bufUsed; ALIGN16 byte lastBlock[WOLFSSL_EVP_BUF_SIZE]; int lastUsed; +#if defined(HAVE_AESGCM) + int ivSz; + ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; + int authTagSz; +#endif } WOLFSSL_EVP_CIPHER_CTX; struct WOLFSSL_EVP_PKEY_CTX { @@ -233,6 +249,7 @@ typedef int WOLFSSL_ENGINE ; typedef WOLFSSL_ENGINE ENGINE; typedef WOLFSSL_EVP_PKEY_CTX EVP_PKEY_CTX; +#define EVP_PKEY_OP_SIGN (1 << 3) #define EVP_PKEY_OP_ENCRYPT (1 << 6) #define EVP_PKEY_OP_DECRYPT (1 << 7) @@ -298,7 +315,8 @@ WOLFSSL_API int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER*, WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx); WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx); - +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_ctrl(WOLFSSL_EVP_CIPHER_CTX *ctx, \ + int type, int arg, void *ptr); WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX*); WOLFSSL_API int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER*); WOLFSSL_API int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c); @@ -356,6 +374,8 @@ WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx); WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx); WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx, int keylen); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_iv_length(WOLFSSL_EVP_CIPHER_CTX* ctx, + int ivLen); WOLFSSL_API int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, unsigned char* dst, unsigned char* src, unsigned int len); @@ -376,6 +396,9 @@ WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, ENGINE* e, const unsigned char* key, int keylen); WOLFSSL_API const unsigned char* wolfSSL_EVP_PKEY_get0_hmac(const WOLFSSL_EVP_PKEY* pkey, size_t* len); +WOLFSSL_API int wolfSSL_EVP_PKEY_sign_init(WOLFSSL_EVP_PKEY_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_PKEY_sign(WOLFSSL_EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen); WOLFSSL_API int wolfSSL_EVP_PKEY_bits(const WOLFSSL_EVP_PKEY *pkey); WOLFSSL_API int wolfSSL_EVP_PKEY_CTX_free(WOLFSSL_EVP_PKEY_CTX *ctx); WOLFSSL_API WOLFSSL_EVP_PKEY_CTX *wolfSSL_EVP_PKEY_CTX_new(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_ENGINE *e); @@ -481,6 +504,9 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc #define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc #define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc +#define EVP_aes_128_gcm wolfSSL_EVP_aes_128_gcm +#define EVP_aes_192_gcm wolfSSL_EVP_aes_192_gcm +#define EVP_aes_256_gcm wolfSSL_EVP_aes_256_gcm #define EVP_aes_128_ecb wolfSSL_EVP_aes_128_ecb #define EVP_aes_192_ecb wolfSSL_EVP_aes_192_ecb #define EVP_aes_256_ecb wolfSSL_EVP_aes_256_ecb @@ -572,6 +598,8 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_PKEY_new_mac_key wolfSSL_EVP_PKEY_new_mac_key #define EVP_MD_CTX_copy wolfSSL_EVP_MD_CTX_copy #define EVP_MD_CTX_copy_ex wolfSSL_EVP_MD_CTX_copy_ex +#define EVP_PKEY_sign_init wolfSSL_EVP_PKEY_sign_init +#define EVP_PKEY_sign wolfSSL_EVP_PKEY_sign #define EVP_PKEY_bits wolfSSL_EVP_PKEY_bits #define EVP_PKEY_CTX_free wolfSSL_EVP_PKEY_CTX_free #define EVP_PKEY_CTX_new wolfSSL_EVP_PKEY_CTX_new @@ -593,6 +621,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_VerifyInit wolfSSL_EVP_VerifyInit #define EVP_VerifyUpdate wolfSSL_EVP_VerifyUpdate +#define EVP_CIPHER_CTX_ctrl wolfSSL_EVP_CIPHER_CTX_ctrl #define EVP_CIPHER_CTX_block_size wolfSSL_EVP_CIPHER_CTX_block_size #define EVP_CIPHER_block_size wolfSSL_EVP_CIPHER_block_size #define EVP_CIPHER_flags wolfSSL_EVP_CIPHER_flags @@ -612,6 +641,21 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define PKCS5_PBKDF2_HMAC_SHA1 wolfSSL_PKCS5_PBKDF2_HMAC_SHA1 +/* OpenSSL compat. ctrl values */ +#define EVP_CTRL_INIT 0x0 +#define EVP_CTRL_SET_KEY_LENGTH 0x1 +#define EVP_CTRL_SET_RC2_KEY_BITS 0x3 /* needed for qt compilation */ + +#define EVP_CTRL_AEAD_SET_IVLEN 0x9 +#define EVP_CTRL_AEAD_GET_TAG 0x10 +#define EVP_CTRL_AEAD_SET_TAG 0x11 +#define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 +#define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN +#define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG +#define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +#define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED +#define EVP_CTRL_GCM_IV_GEN 0x13 + #ifndef EVP_MAX_MD_SIZE #define EVP_MAX_MD_SIZE 64 /* sha512 */ #endif diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index 2920b3f17..aeaefdc87 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -35,6 +35,8 @@ /* Padding types */ #define RSA_PKCS1_PADDING 0 #define RSA_PKCS1_OAEP_PADDING 1 +#define RSA_NO_PADDING 3 +#define RSA_PKCS1_PSS_PADDING 6 #ifndef WOLFSSL_RSA_TYPE_DEFINED /* guard on redeclaration */ typedef struct WOLFSSL_RSA WOLFSSL_RSA; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 10580376e..5565aaf73 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -523,6 +523,7 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #define RSA_free wolfSSL_RSA_free #define RSA_generate_key wolfSSL_RSA_generate_key #define SSL_CTX_set_tmp_rsa_callback wolfSSL_CTX_set_tmp_rsa_callback +#define RSA_print wolfSSL_RSA_print #define PEM_def_callback wolfSSL_PEM_def_callback diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index be0e365f4..a8dd9e71f 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -960,6 +960,9 @@ WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_verify_cb(WOLFSSL_X509_STORE_CTX *c WOLFSSL_X509_STORE_CTX_verify_cb verify_cb); WOLFSSL_API int wolfSSL_i2d_X509_NAME(WOLFSSL_X509_NAME* n, unsigned char** out); +#ifndef NO_RSA +WOLFSSL_API int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset); +#endif WOLFSSL_API int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); WOLFSSL_API char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME*, char*, int); WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509*); @@ -989,6 +992,7 @@ WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_X509_NAME_ENTRY_get_data(WOLFSSL_X509_N WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_new(void); WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_ASN1_STRING_type_new(int type); +WOLFSSL_API int wolfSSL_ASN1_STRING_type(const WOLFSSL_ASN1_STRING* asn1); WOLFSSL_API void wolfSSL_ASN1_STRING_free(WOLFSSL_ASN1_STRING* asn1); WOLFSSL_API int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data, int dataSz); diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 71fc7b841..3f047bd47 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -145,6 +145,11 @@ typedef struct Aes { #endif #ifdef HAVE_AESGCM ALIGN16 byte H[AES_BLOCK_SIZE]; +#ifdef OPENSSL_EXTRA + word64 aadH[2]; /* additional authenticated data hash */ + word64 aadLen; /* additional authenticated data len */ +#endif + #ifdef GCM_TABLE /* key-based fast multiplication table. */ ALIGN16 byte M0[256][AES_BLOCK_SIZE];