From 5f5593a30e3b79496ef9a90993c61fcd03fa6303 Mon Sep 17 00:00:00 2001
From: Paul Bakker
Date: Wed, 16 Jan 2013 13:26:56 +0100
Subject: [PATCH] Handle encryption with private key and decryption with public
key as per RFC 2313 (cherry picked from commit
e6ee41f932f71e86b2d33a9ed12ba4e3d172b1ca)
---
ChangeLog | 2 ++
library/rsa.c | 67 ++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 52 insertions(+), 17 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 453ee25bd..c86e441e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,8 @@ Bugfix
Pégourié-Gonnard)
* Added max length check for rsa_pkcs1_sign with PKCS#1 v2.1
* Memory leak when using RSA_PKCS_V21 operations fixed
+ * Handle encryption with private key and decryption with public key as per
+ RFC 2313
Security
* Fixed potential memory zeroization on miscrafted RSA key (found by Eloi
diff --git a/library/rsa.c b/library/rsa.c
index 0ddada264..614b23c84 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -386,23 +386,34 @@ int rsa_pkcs1_encrypt( rsa_context *ctx,
nb_pad = olen - 3 - ilen;
*p++ = 0;
- *p++ = RSA_CRYPT;
-
- while( nb_pad-- > 0 )
+ if( mode == RSA_PUBLIC )
{
- int rng_dl = 100;
+ *p++ = RSA_CRYPT;
- do {
- ret = f_rng( p_rng, p, 1 );
- } while( *p == 0 && --rng_dl && ret == 0 );
+ while( nb_pad-- > 0 )
+ {
+ int rng_dl = 100;
- // Check if RNG failed to generate data
- //
- if( rng_dl == 0 || ret != 0)
- return POLARSSL_ERR_RSA_RNG_FAILED + ret;
+ do {
+ ret = f_rng( p_rng, p, 1 );
+ } while( *p == 0 && --rng_dl && ret == 0 );
- p++;
+ // 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;
@@ -476,6 +487,7 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
int ret;
size_t ilen;
unsigned char *p;
+ unsigned char bt;
unsigned char buf[1024];
#if defined(POLARSSL_PKCS1_V21)
unsigned char lhash[POLARSSL_MD_MAX_SIZE];
@@ -502,16 +514,37 @@ int rsa_pkcs1_decrypt( rsa_context *ctx,
{
case RSA_PKCS_V15:
- if( *p++ != 0 || *p++ != RSA_CRYPT )
+ if( *p++ != 0 )
return( POLARSSL_ERR_RSA_INVALID_PADDING );
-
- while( *p != 0 )
+
+ bt = *p++;
+ if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) ||
+ ( bt != RSA_SIGN && mode == RSA_PUBLIC ) )
{
- if( p >= buf + ilen - 1 )
+ 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++;
}
- 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)