mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-22 11:25:42 +01:00
Split up the RSA PKCS#1 encrypt, decrypt, sign and verify functions
Split rsa_pkcs1_encrypt() into rsa_rsaes_oaep_encrypt() and rsa_rsaes_pkcs1_v15_encrypt() Split rsa_pkcs1_decrypt() into rsa_rsaes_oaep_decrypt() and rsa_rsaes_pkcs1_v15_decrypt() Split rsa_pkcs1_sign() into rsa_rsassa_pss_sign() and rsa_rsassa_pkcs1_v15_sign() Split rsa_pkcs1_verify() into rsa_rsassa_pss_verify() and rsa_rsassa_pkcs1_v15_verify() The original functions exist as generic wrappers to these functions.
This commit is contained in:
parent
e3e4a59622
commit
b386913f8b
@ -7,6 +7,11 @@ Bugfix
|
||||
128-bits (found by Yawning Angel)
|
||||
* Fixes for 64-bit compilation with MS Visual Studio
|
||||
|
||||
Changes
|
||||
* Internally split up rsa_pkcs1_encrypt(), rsa_pkcs1_decrypt(),
|
||||
rsa_pkcs1_sign() and rsa_pkcs1_verify() to separate PKCS#1 v1.5 and
|
||||
PKCS#1 v2.1 functions
|
||||
|
||||
Security
|
||||
* Removed further timing differences during SSL message decryption in
|
||||
ssl_decrypt_buf()
|
||||
|
@ -255,7 +255,9 @@ int rsa_private( rsa_context *ctx,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Add the message padding, then do an RSA operation
|
||||
* \brief Generic wrapper to perform a PKCS#1 encryption using the
|
||||
* mode from the context. Add the message padding, then do an
|
||||
* RSA operation.
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding)
|
||||
@ -278,7 +280,55 @@ int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Do an RSA operation, then remove the message padding
|
||||
* \brief Perform a PKCS#1 v1.5 encryption (RSAES-PKCS1-v1_5-ENCRYPT)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for padding)
|
||||
* \param p_rng RNG parameter
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param ilen contains the plaintext length
|
||||
* \param input buffer holding the data to be encrypted
|
||||
* \param output buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode, size_t ilen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v2.1 OAEP encryption (RSAES-OAEP-ENCRYPT)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for padding and PKCS#1 v2.1 encoding)
|
||||
* \param p_rng RNG parameter
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param ilen contains the plaintext length
|
||||
* \param input buffer holding the data to be encrypted
|
||||
* \param output buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode, size_t ilen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief Generic wrapper to perform a PKCS#1 decryption using the
|
||||
* mode from the context. Do an RSA operation, then remove
|
||||
* the message padding
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
@ -300,7 +350,53 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
size_t output_max_len );
|
||||
|
||||
/**
|
||||
* \brief Do a private RSA to sign a message digest
|
||||
* \brief Perform a PKCS#1 v1.5 decryption (RSAES-PKCS1-v1_5-DECRYPT)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param olen will contain the plaintext length
|
||||
* \param input buffer holding the encrypted data
|
||||
* \param output buffer that will hold the plaintext
|
||||
* \param output_max_len maximum length of the output buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
|
||||
* an error is thrown.
|
||||
*/
|
||||
int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v2.1 OAEP decryption (RSAES-OAEP-DECRYPT)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param olen will contain the plaintext length
|
||||
* \param input buffer holding the encrypted data
|
||||
* \param output buffer that will hold the plaintext
|
||||
* \param output_max_len maximum length of the output buffer
|
||||
*
|
||||
* \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The output buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
|
||||
* an error is thrown.
|
||||
*/
|
||||
int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len );
|
||||
|
||||
/**
|
||||
* \brief Generic wrapper to perform a PKCS#1 signature using the
|
||||
* mode from the context. Do a private RSA operation to sign
|
||||
* a message digest
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding)
|
||||
@ -333,7 +429,65 @@ int rsa_pkcs1_sign( rsa_context *ctx,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Do a public RSA and check the message digest
|
||||
* \brief Perform a PKCS#1 v1.5 signature (RSASSA-PKCS1-v1_5-SIGN)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if the signing operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v2.1 PSS signature (RSASSA-PSS-SIGN)
|
||||
*
|
||||
* \param ctx RSA context
|
||||
* \param f_rng RNG function (Needed for PKCS#1 v2.1 encoding)
|
||||
* \param p_rng RNG parameter
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer that will hold the ciphertext
|
||||
*
|
||||
* \return 0 if the signing operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*
|
||||
* \note In case of PKCS#1 v2.1 encoding keep in mind that
|
||||
* the hash_id in the RSA context is the one used for the
|
||||
* encoding. hash_id in the function call is the type of hash
|
||||
* that is encoded. According to RFC 3447 it is advised to
|
||||
* keep both hashes the same.
|
||||
*/
|
||||
int rsa_rsassa_pss_sign( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Generic wrapper to perform a PKCS#1 verification using the
|
||||
* mode from the context. Do a public RSA operation and check
|
||||
* the message digest
|
||||
*
|
||||
* \param ctx points to an RSA public key
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
@ -361,6 +515,59 @@ int rsa_pkcs1_verify( rsa_context *ctx,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v1.5 verification (RSASSA-PKCS1-v1_5-VERIFY)
|
||||
*
|
||||
* \param ctx points to an RSA public key
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer holding the ciphertext
|
||||
*
|
||||
* \return 0 if the verify operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*/
|
||||
int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Perform a PKCS#1 v2.1 PSS verification (RSASSA-PSS-VERIFY)
|
||||
* \brief Do a public RSA and check the message digest
|
||||
*
|
||||
* \param ctx points to an RSA public key
|
||||
* \param mode RSA_PUBLIC or RSA_PRIVATE
|
||||
* \param hash_id SIG_RSA_RAW, SIG_RSA_MD{2,4,5} or SIG_RSA_SHA{1,224,256,384,512}
|
||||
* \param hashlen message digest length (for SIG_RSA_RAW only)
|
||||
* \param hash buffer holding the message digest
|
||||
* \param sig buffer holding the ciphertext
|
||||
*
|
||||
* \return 0 if the verify operation was successful,
|
||||
* or an POLARSSL_ERR_RSA_XXX error code
|
||||
*
|
||||
* \note The "sig" buffer must be as large as the size
|
||||
* of ctx->N (eg. 128 bytes if RSA-1024 is used).
|
||||
*
|
||||
* \note In case of PKCS#1 v2.1 encoding keep in mind that
|
||||
* the hash_id in the RSA context is the one used for the
|
||||
* verification. hash_id in the function call is the type of hash
|
||||
* that is verified. According to RFC 3447 it is advised to
|
||||
* keep both hashes the same.
|
||||
*/
|
||||
int rsa_rsassa_pss_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig );
|
||||
|
||||
/**
|
||||
* \brief Free the components of an RSA key
|
||||
*
|
||||
|
787
library/rsa.c
787
library/rsa.c
@ -361,79 +361,33 @@ static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, size_
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
/*
|
||||
* Add the message padding, then do an RSA operation
|
||||
* Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
|
||||
*/
|
||||
int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||
int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode, size_t ilen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
size_t nb_pad, olen;
|
||||
size_t olen;
|
||||
int ret;
|
||||
unsigned char *p = output;
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
unsigned int hlen;
|
||||
const md_info_t *md_info;
|
||||
md_context_t md_ctx;
|
||||
#endif
|
||||
|
||||
olen = ctx->len;
|
||||
|
||||
if( f_rng == NULL )
|
||||
if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
|
||||
if( olen < ilen + 11 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
nb_pad = olen - 3 - ilen;
|
||||
|
||||
*p++ = 0;
|
||||
if( mode == RSA_PUBLIC )
|
||||
{
|
||||
*p++ = RSA_CRYPT;
|
||||
|
||||
while( nb_pad-- > 0 )
|
||||
{
|
||||
int rng_dl = 100;
|
||||
|
||||
do {
|
||||
ret = f_rng( p_rng, p, 1 );
|
||||
} while( *p == 0 && --rng_dl && ret == 0 );
|
||||
|
||||
// Check if RNG failed to generate data
|
||||
//
|
||||
if( rng_dl == 0 || ret != 0)
|
||||
return POLARSSL_ERR_RSA_RNG_FAILED + ret;
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = RSA_SIGN;
|
||||
|
||||
while( nb_pad-- > 0 )
|
||||
*p++ = 0xFF;
|
||||
}
|
||||
|
||||
*p++ = 0;
|
||||
memcpy( p, input, ilen );
|
||||
break;
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
case RSA_PKCS_V21:
|
||||
|
||||
md_info = md_info_from_type( ctx->hash_id );
|
||||
|
||||
if( md_info == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
olen = ctx->len;
|
||||
hlen = md_get_size( md_info );
|
||||
|
||||
if( olen < ilen + 2 * hlen + 2 || f_rng == NULL )
|
||||
@ -471,13 +425,68 @@ int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||
&md_ctx );
|
||||
|
||||
md_free_ctx( &md_ctx );
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
return( ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, output, output )
|
||||
: rsa_private( ctx, output, output ) );
|
||||
}
|
||||
#endif /* POLARSSL_PKCS1_V21 */
|
||||
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
|
||||
*/
|
||||
int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode, size_t ilen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
size_t nb_pad, olen;
|
||||
int ret;
|
||||
unsigned char *p = output;
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V15 || f_rng == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
olen = ctx->len;
|
||||
|
||||
if( olen < ilen + 11 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
nb_pad = olen - 3 - ilen;
|
||||
|
||||
*p++ = 0;
|
||||
if( mode == RSA_PUBLIC )
|
||||
{
|
||||
*p++ = RSA_CRYPT;
|
||||
|
||||
while( nb_pad-- > 0 )
|
||||
{
|
||||
int rng_dl = 100;
|
||||
|
||||
do {
|
||||
ret = f_rng( p_rng, p, 1 );
|
||||
} while( *p == 0 && --rng_dl && ret == 0 );
|
||||
|
||||
// Check if RNG failed to generate data
|
||||
//
|
||||
if( rng_dl == 0 || ret != 0)
|
||||
return POLARSSL_ERR_RSA_RNG_FAILED + ret;
|
||||
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = RSA_SIGN;
|
||||
|
||||
while( nb_pad-- > 0 )
|
||||
*p++ = 0xFF;
|
||||
}
|
||||
|
||||
*p++ = 0;
|
||||
memcpy( p, input, ilen );
|
||||
|
||||
return( ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, output, output )
|
||||
@ -485,9 +494,37 @@ int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an RSA operation, then remove the message padding
|
||||
* Add the message padding, then do an RSA operation
|
||||
*/
|
||||
int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
int rsa_pkcs1_encrypt( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode, size_t ilen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output )
|
||||
{
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
return rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
|
||||
input, output );
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
case RSA_PKCS_V21:
|
||||
return rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
|
||||
ilen, input, output );
|
||||
#endif
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
|
||||
*/
|
||||
int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
@ -496,14 +533,14 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
int ret;
|
||||
size_t ilen;
|
||||
unsigned char *p;
|
||||
unsigned char bt;
|
||||
unsigned char buf[POLARSSL_MPI_MAX_SIZE];
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
unsigned char lhash[POLARSSL_MD_MAX_SIZE];
|
||||
unsigned int hlen;
|
||||
const md_info_t *md_info;
|
||||
md_context_t md_ctx;
|
||||
#endif
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V21 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
ilen = ctx->len;
|
||||
|
||||
@ -519,46 +556,6 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
|
||||
p = buf;
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
|
||||
if( *p++ != 0 )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
bt = *p++;
|
||||
if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) ||
|
||||
( bt != RSA_SIGN && mode == RSA_PUBLIC ) )
|
||||
{
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
if( bt == RSA_CRYPT )
|
||||
{
|
||||
while( *p != 0 && p < buf + ilen - 1 )
|
||||
p++;
|
||||
|
||||
if( *p != 0 || p >= buf + ilen - 1 )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while( *p == 0xFF && p < buf + ilen - 1 )
|
||||
p++;
|
||||
|
||||
if( *p != 0 || p >= buf + ilen - 1 )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
case RSA_PKCS_V21:
|
||||
|
||||
if( *p++ != 0 )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
@ -603,12 +600,77 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
if( *p++ != 0x01 )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
break;
|
||||
#endif
|
||||
if (ilen - (p - buf) > output_max_len)
|
||||
return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );
|
||||
|
||||
default:
|
||||
*olen = ilen - (p - buf);
|
||||
memcpy( output, p, *olen );
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
#endif /* POLARSSL_PKCS1_V21 */
|
||||
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
|
||||
*/
|
||||
int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len)
|
||||
{
|
||||
int ret;
|
||||
size_t ilen;
|
||||
unsigned char *p;
|
||||
unsigned char bt;
|
||||
unsigned char buf[POLARSSL_MPI_MAX_SIZE];
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V15 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
ilen = ctx->len;
|
||||
|
||||
if( ilen < 16 || ilen > sizeof( buf ) )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
ret = ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, input, buf )
|
||||
: rsa_private( ctx, input, buf );
|
||||
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
p = buf;
|
||||
|
||||
if( *p++ != 0 )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
bt = *p++;
|
||||
if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) ||
|
||||
( bt != RSA_SIGN && mode == RSA_PUBLIC ) )
|
||||
{
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
if( bt == RSA_CRYPT )
|
||||
{
|
||||
while( *p != 0 && p < buf + ilen - 1 )
|
||||
p++;
|
||||
|
||||
if( *p != 0 || p >= buf + ilen - 1 )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
while( *p == 0xFF && p < buf + ilen - 1 )
|
||||
p++;
|
||||
|
||||
if( *p != 0 || p >= buf + ilen - 1 )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
if (ilen - (p - buf) > output_max_len)
|
||||
@ -621,9 +683,36 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an RSA operation to sign the message digest
|
||||
* Do an RSA operation, then remove the message padding
|
||||
*/
|
||||
int rsa_pkcs1_sign( rsa_context *ctx,
|
||||
int rsa_pkcs1_decrypt( rsa_context *ctx,
|
||||
int mode, size_t *olen,
|
||||
const unsigned char *input,
|
||||
unsigned char *output,
|
||||
size_t output_max_len)
|
||||
{
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
return rsa_rsaes_pkcs1_v15_decrypt( ctx, mode, olen, input, output,
|
||||
output_max_len );
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
case RSA_PKCS_V21:
|
||||
return rsa_rsaes_oaep_decrypt( ctx, mode, NULL, 0, olen, input,
|
||||
output, output_max_len );
|
||||
#endif
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
|
||||
*/
|
||||
int rsa_rsassa_pss_sign( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
@ -632,25 +721,132 @@ int rsa_pkcs1_sign( rsa_context *ctx,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
size_t nb_pad, olen;
|
||||
size_t olen;
|
||||
unsigned char *p = sig;
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
unsigned char salt[POLARSSL_MD_MAX_SIZE];
|
||||
unsigned int slen, hlen, offset = 0;
|
||||
int ret;
|
||||
size_t msb;
|
||||
const md_info_t *md_info;
|
||||
md_context_t md_ctx;
|
||||
#else
|
||||
(void) f_rng;
|
||||
(void) p_rng;
|
||||
#endif
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
olen = ctx->len;
|
||||
|
||||
switch( ctx->padding )
|
||||
switch( hash_id )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
case SIG_RSA_MD2:
|
||||
case SIG_RSA_MD4:
|
||||
case SIG_RSA_MD5:
|
||||
hashlen = 16;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA1:
|
||||
hashlen = 20;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA224:
|
||||
hashlen = 28;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA256:
|
||||
hashlen = 32;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA384:
|
||||
hashlen = 48;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA512:
|
||||
hashlen = 64;
|
||||
break;
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
md_info = md_info_from_type( ctx->hash_id );
|
||||
if( md_info == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
hlen = md_get_size( md_info );
|
||||
slen = hlen;
|
||||
|
||||
if( olen < hlen + slen + 2 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
memset( sig, 0, olen );
|
||||
|
||||
msb = mpi_msb( &ctx->N ) - 1;
|
||||
|
||||
// Generate salt of length slen
|
||||
//
|
||||
if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
|
||||
return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
|
||||
|
||||
// Note: EMSA-PSS encoding is over the length of N - 1 bits
|
||||
//
|
||||
msb = mpi_msb( &ctx->N ) - 1;
|
||||
p += olen - hlen * 2 - 2;
|
||||
*p++ = 0x01;
|
||||
memcpy( p, salt, slen );
|
||||
p += slen;
|
||||
|
||||
md_init_ctx( &md_ctx, md_info );
|
||||
|
||||
// Generate H = Hash( M' )
|
||||
//
|
||||
md_starts( &md_ctx );
|
||||
md_update( &md_ctx, p, 8 );
|
||||
md_update( &md_ctx, hash, hashlen );
|
||||
md_update( &md_ctx, salt, slen );
|
||||
md_finish( &md_ctx, p );
|
||||
|
||||
// Compensate for boundary condition when applying mask
|
||||
//
|
||||
if( msb % 8 == 0 )
|
||||
offset = 1;
|
||||
|
||||
// maskedDB: Apply dbMask to DB
|
||||
//
|
||||
mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
|
||||
|
||||
md_free_ctx( &md_ctx );
|
||||
|
||||
msb = mpi_msb( &ctx->N ) - 1;
|
||||
sig[0] &= 0xFF >> ( olen * 8 - msb );
|
||||
|
||||
p += hlen;
|
||||
*p++ = 0xBC;
|
||||
|
||||
return( ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, sig, sig )
|
||||
: rsa_private( ctx, sig, sig ) );
|
||||
}
|
||||
#endif /* POLARSSL_PKCS1_V21 */
|
||||
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
|
||||
*/
|
||||
/*
|
||||
* Do an RSA operation to sign the message digest
|
||||
*/
|
||||
int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
size_t nb_pad, olen;
|
||||
unsigned char *p = sig;
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V15 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
olen = ctx->len;
|
||||
|
||||
switch( hash_id )
|
||||
{
|
||||
@ -748,116 +944,45 @@ int rsa_pkcs1_sign( rsa_context *ctx,
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
case RSA_PKCS_V21:
|
||||
|
||||
if( f_rng == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
switch( hash_id )
|
||||
{
|
||||
case SIG_RSA_MD2:
|
||||
case SIG_RSA_MD4:
|
||||
case SIG_RSA_MD5:
|
||||
hashlen = 16;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA1:
|
||||
hashlen = 20;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA224:
|
||||
hashlen = 28;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA256:
|
||||
hashlen = 32;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA384:
|
||||
hashlen = 48;
|
||||
break;
|
||||
|
||||
case SIG_RSA_SHA512:
|
||||
hashlen = 64;
|
||||
break;
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
}
|
||||
|
||||
md_info = md_info_from_type( ctx->hash_id );
|
||||
if( md_info == NULL )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
hlen = md_get_size( md_info );
|
||||
slen = hlen;
|
||||
|
||||
if( olen < hlen + slen + 2 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
memset( sig, 0, olen );
|
||||
|
||||
msb = mpi_msb( &ctx->N ) - 1;
|
||||
|
||||
// Generate salt of length slen
|
||||
//
|
||||
if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
|
||||
return( POLARSSL_ERR_RSA_RNG_FAILED + ret );
|
||||
|
||||
// Note: EMSA-PSS encoding is over the length of N - 1 bits
|
||||
//
|
||||
msb = mpi_msb( &ctx->N ) - 1;
|
||||
p += olen - hlen * 2 - 2;
|
||||
*p++ = 0x01;
|
||||
memcpy( p, salt, slen );
|
||||
p += slen;
|
||||
|
||||
md_init_ctx( &md_ctx, md_info );
|
||||
|
||||
// Generate H = Hash( M' )
|
||||
//
|
||||
md_starts( &md_ctx );
|
||||
md_update( &md_ctx, p, 8 );
|
||||
md_update( &md_ctx, hash, hashlen );
|
||||
md_update( &md_ctx, salt, slen );
|
||||
md_finish( &md_ctx, p );
|
||||
|
||||
// Compensate for boundary condition when applying mask
|
||||
//
|
||||
if( msb % 8 == 0 )
|
||||
offset = 1;
|
||||
|
||||
// maskedDB: Apply dbMask to DB
|
||||
//
|
||||
mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );
|
||||
|
||||
md_free_ctx( &md_ctx );
|
||||
|
||||
msb = mpi_msb( &ctx->N ) - 1;
|
||||
sig[0] &= 0xFF >> ( olen * 8 - msb );
|
||||
|
||||
p += hlen;
|
||||
*p++ = 0xBC;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
return( ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, sig, sig )
|
||||
: rsa_private( ctx, sig, sig ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an RSA operation and check the message digest
|
||||
* Do an RSA operation to sign the message digest
|
||||
*/
|
||||
int rsa_pkcs1_verify( rsa_context *ctx,
|
||||
int rsa_pkcs1_sign( rsa_context *ctx,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
return rsa_rsassa_pkcs1_v15_sign( ctx, mode, hash_id,
|
||||
hashlen, hash, sig );
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
case RSA_PKCS_V21:
|
||||
return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, hash_id,
|
||||
hashlen, hash, sig );
|
||||
#endif
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
|
||||
*/
|
||||
int rsa_rsassa_pss_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
@ -865,17 +990,19 @@ int rsa_pkcs1_verify( rsa_context *ctx,
|
||||
unsigned char *sig )
|
||||
{
|
||||
int ret;
|
||||
size_t len, siglen;
|
||||
unsigned char *p, c;
|
||||
size_t siglen;
|
||||
unsigned char *p;
|
||||
unsigned char buf[POLARSSL_MPI_MAX_SIZE];
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
unsigned char result[POLARSSL_MD_MAX_SIZE];
|
||||
unsigned char zeros[8];
|
||||
unsigned int hlen;
|
||||
size_t slen, msb;
|
||||
const md_info_t *md_info;
|
||||
md_context_t md_ctx;
|
||||
#endif
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V21 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
siglen = ctx->len;
|
||||
|
||||
if( siglen < 16 || siglen > sizeof( buf ) )
|
||||
@ -890,88 +1017,6 @@ int rsa_pkcs1_verify( rsa_context *ctx,
|
||||
|
||||
p = buf;
|
||||
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
|
||||
if( *p++ != 0 || *p++ != RSA_SIGN )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
while( *p != 0 )
|
||||
{
|
||||
if( p >= buf + siglen - 1 || *p != 0xFF )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
|
||||
len = siglen - ( p - buf );
|
||||
|
||||
if( len == 33 && hash_id == SIG_RSA_SHA1 )
|
||||
{
|
||||
if( memcmp( p, ASN1_HASH_SHA1_ALT, 13 ) == 0 &&
|
||||
memcmp( p + 13, hash, 20 ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
if( len == 34 )
|
||||
{
|
||||
c = p[13];
|
||||
p[13] = 0;
|
||||
|
||||
if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
|
||||
if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
|
||||
( c == 4 && hash_id == SIG_RSA_MD4 ) ||
|
||||
( c == 5 && hash_id == SIG_RSA_MD5 ) )
|
||||
{
|
||||
if( memcmp( p + 18, hash, 16 ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
}
|
||||
|
||||
if( len == 35 && hash_id == SIG_RSA_SHA1 )
|
||||
{
|
||||
if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
|
||||
memcmp( p + 15, hash, 20 ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
|
||||
( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
|
||||
( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
|
||||
( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
|
||||
{
|
||||
c = p[1] - 17;
|
||||
p[1] = 17;
|
||||
p[14] = 0;
|
||||
|
||||
if( p[18] == c &&
|
||||
memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
|
||||
memcmp( p + 19, hash, c ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
if( len == hashlen && hash_id == SIG_RSA_RAW )
|
||||
{
|
||||
if( memcmp( p, hash, hashlen ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
case RSA_PKCS_V21:
|
||||
|
||||
if( buf[siglen - 1] != 0xBC )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
@ -1062,15 +1107,143 @@ int rsa_pkcs1_verify( rsa_context *ctx,
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
#endif
|
||||
}
|
||||
#endif /* POLARSSL_PKCS1_V21 */
|
||||
|
||||
default:
|
||||
/*
|
||||
* Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
|
||||
*/
|
||||
int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
int ret;
|
||||
size_t len, siglen;
|
||||
unsigned char *p, c;
|
||||
unsigned char buf[POLARSSL_MPI_MAX_SIZE];
|
||||
|
||||
if( ctx->padding != RSA_PKCS_V15 )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
siglen = ctx->len;
|
||||
|
||||
if( siglen < 16 || siglen > sizeof( buf ) )
|
||||
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
|
||||
|
||||
ret = ( mode == RSA_PUBLIC )
|
||||
? rsa_public( ctx, sig, buf )
|
||||
: rsa_private( ctx, sig, buf );
|
||||
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
p = buf;
|
||||
|
||||
if( *p++ != 0 || *p++ != RSA_SIGN )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
|
||||
while( *p != 0 )
|
||||
{
|
||||
if( p >= buf + siglen - 1 || *p != 0xFF )
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
|
||||
len = siglen - ( p - buf );
|
||||
|
||||
if( len == 33 && hash_id == SIG_RSA_SHA1 )
|
||||
{
|
||||
if( memcmp( p, ASN1_HASH_SHA1_ALT, 13 ) == 0 &&
|
||||
memcmp( p + 13, hash, 20 ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
if( len == 34 )
|
||||
{
|
||||
c = p[13];
|
||||
p[13] = 0;
|
||||
|
||||
if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
|
||||
if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
|
||||
( c == 4 && hash_id == SIG_RSA_MD4 ) ||
|
||||
( c == 5 && hash_id == SIG_RSA_MD5 ) )
|
||||
{
|
||||
if( memcmp( p + 18, hash, 16 ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
}
|
||||
|
||||
if( len == 35 && hash_id == SIG_RSA_SHA1 )
|
||||
{
|
||||
if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
|
||||
memcmp( p + 15, hash, 20 ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
|
||||
( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
|
||||
( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
|
||||
( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
|
||||
{
|
||||
c = p[1] - 17;
|
||||
p[1] = 17;
|
||||
p[14] = 0;
|
||||
|
||||
if( p[18] == c &&
|
||||
memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
|
||||
memcmp( p + 19, hash, c ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
if( len == hashlen && hash_id == SIG_RSA_RAW )
|
||||
{
|
||||
if( memcmp( p, hash, hashlen ) == 0 )
|
||||
return( 0 );
|
||||
else
|
||||
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
|
||||
}
|
||||
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an RSA operation and check the message digest
|
||||
*/
|
||||
int rsa_pkcs1_verify( rsa_context *ctx,
|
||||
int mode,
|
||||
int hash_id,
|
||||
unsigned int hashlen,
|
||||
const unsigned char *hash,
|
||||
unsigned char *sig )
|
||||
{
|
||||
switch( ctx->padding )
|
||||
{
|
||||
case RSA_PKCS_V15:
|
||||
return rsa_rsassa_pkcs1_v15_verify( ctx, mode, hash_id,
|
||||
hashlen, hash, sig );
|
||||
|
||||
#if defined(POLARSSL_PKCS1_V21)
|
||||
case RSA_PKCS_V21:
|
||||
return rsa_rsassa_pss_verify( ctx, mode, hash_id,
|
||||
hashlen, hash, sig );
|
||||
#endif
|
||||
|
||||
default:
|
||||
return( POLARSSL_ERR_RSA_INVALID_PADDING );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the components of an RSA key
|
||||
|
Loading…
Reference in New Issue
Block a user