From f9988516420577fabd6c8bc3a199d73ad31fc9ce Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 14 Apr 2016 09:33:25 -0600 Subject: [PATCH] fix check on RSA key size --- wolfcrypt/src/error.c | 3 +++ wolfcrypt/src/rsa.c | 41 +++++++++++++++++++++++++++------ wolfcrypt/user-crypto/src/rsa.c | 32 +++++++++++++++++++++---- wolfssl/wolfcrypt/error-crypt.h | 2 ++ 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index eb28981f1..5ad5d77a5 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -377,6 +377,9 @@ const char* wc_GetErrorString(int error) case WC_PENDING_E: return "wolfCrypt Operation Pending (would block / eagain) error"; + case WC_KEY_SIZE_E: + return "Key size error, either too small or large"; + default: return "unknown error number"; diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index ea5bf381f..690a7c804 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -413,8 +413,7 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, } #endif - if ((ret = wc_Hash(hType, optLabel, labelLen, - lHash, hLen)) != 0) { + if ((ret = wc_Hash(hType, optLabel, labelLen, lHash, hLen)) != 0) { WOLFSSL_MSG("OAEP hash type possibly not supported or lHash to small"); #ifdef WOLFSSL_SMALL_STACK XFREE(lHash, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -542,21 +541,33 @@ static int wc_RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, word32 pkcsBlockLen, byte padValue, WC_RNG* rng) { - if (inputLen == 0) - return 0; + if (inputLen == 0 || pkcsBlockLen == 0) { + return BAD_FUNC_ARG; + } pkcsBlock[0] = 0x0; /* set first byte to zero and advance */ pkcsBlock++; pkcsBlockLen--; pkcsBlock[0] = padValue; /* insert padValue */ - if (padValue == RSA_BLOCK_TYPE_1) + if (padValue == RSA_BLOCK_TYPE_1) { + if (pkcsBlockLen < inputLen + 2) { + return RSA_PAD_E; + } + /* pad with 0xff bytes */ XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2); + } else { /* pad with non-zero random bytes */ - word32 padLen = pkcsBlockLen - inputLen - 1, i; - int ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); + word32 padLen, i; + int ret; + if (pkcsBlockLen < inputLen + 1) { + return RSA_PAD_E; + } + + padLen = pkcsBlockLen - inputLen - 1; + ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); if (ret != 0) return ret; @@ -701,6 +712,10 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, i = 1, outputLen; + if (pkcsBlockLen == 0) { + return BAD_FUNC_ARG; + } + if (pkcsBlock[0] != 0x0) /* skip past zero */ invalid = 1; pkcsBlock++; pkcsBlockLen--; @@ -882,6 +897,10 @@ int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, if (sz > (int)outLen) return RSA_BUFFER_E; + if (sz < RSA_MIN_PAD_SZ) { + return WC_KEY_SIZE_E; + } + if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) return RSA_BUFFER_E; @@ -925,6 +944,10 @@ int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out, if (sz > (int)outLen) return RSA_BUFFER_E; + if (sz < RSA_MIN_PAD_SZ) { + return WC_KEY_SIZE_E; + } + if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) return RSA_BUFFER_E; @@ -1180,6 +1203,10 @@ int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, if (sz > (int)outLen) return RSA_BUFFER_E; + if (sz < RSA_MIN_PAD_SZ) { + return WC_KEY_SIZE_E; + } + if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) return RSA_BUFFER_E; diff --git a/wolfcrypt/user-crypto/src/rsa.c b/wolfcrypt/user-crypto/src/rsa.c index a3df104a3..748c420c4 100644 --- a/wolfcrypt/user-crypto/src/rsa.c +++ b/wolfcrypt/user-crypto/src/rsa.c @@ -528,20 +528,33 @@ int SetRsaInternal(WOLFSSL_RSA* rsa) static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, word32 pkcsBlockLen, byte padValue, WC_RNG* rng) { - if (inputLen == 0) - return 0; + if (inputLen == 0 || pkcsBlockLen == 0) { + return USER_CRYPTO_ERROR; + } pkcsBlock[0] = 0x0; /* set first byte to zero and advance */ pkcsBlock++; pkcsBlockLen--; pkcsBlock[0] = padValue; /* insert padValue */ - if (padValue == RSA_BLOCK_TYPE_1) + if (padValue == RSA_BLOCK_TYPE_1) { + if (pkcsBlockLen < inputLen + 2) { + return USER_CRYPTO_ERROR; + } + /* pad with 0xff bytes */ XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2); + } else { /* pad with non-zero random bytes */ - word32 padLen = pkcsBlockLen - inputLen - 1, i; - int ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); + word32 padLen, i; + int ret; + + if (pkcsBlockLen < inputLen + 1) { + return USER_CRYPTO_ERROR; + } + + padLen = pkcsBlockLen - inputLen - 1; + ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); if (ret != 0) return ret; @@ -568,6 +581,10 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, i = 1, outputLen; + if (pkcsBlockLen == 0) { + return USER_CRYPTO_ERROR; + } + if (pkcsBlock[0] != 0x0) /* skip past zero */ invalid = 1; pkcsBlock++; pkcsBlockLen--; @@ -1612,6 +1629,11 @@ int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, return USER_CRYPTO_ERROR; } + if (sz < RSA_MIN_PAD_SZ) { + USER_DEBUG(("Key size is too small\n")); + return USER_CRYPTO_ERROR; + } + if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) { USER_DEBUG(("Bad argument inLen to wc_RsaSSL_Sign\n")); return USER_CRYPTO_ERROR; diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index 523e380b4..fe1aef3e5 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -169,6 +169,8 @@ enum { HASH_TYPE_E = -232, /* Hash Type not enabled/available */ WC_PENDING_E = -233, /* wolfCrypt operation pending (would block) */ + WC_KEY_SIZE_E = -234, /* Key size error, either too small or large */ + MIN_CODE_E = -300 /* errors -101 - -299 */ /* add new companion error id strings for any new error codes