diff mbox

[U-Boot,2/4] rsa: Verify RSA padding programatically

Message ID 010101584549e4bc-5b633e70-c111-41b7-a59e-ace2517755ef-000000@us-west-2.amazonses.com
State Accepted
Commit da29f2991d75fc8aa3289407a0e686a4a22f8c9e
Delegated to: Tom Rini
Headers show

Commit Message

aduda Nov. 8, 2016, 6:53 p.m. UTC
From: Andrew Duda <aduda@meraki.com>

Padding verification was done against static SHA/RSA pair arrays which
take up a lot of static memory, are mostly 0xff, and cannot be reused
for additional SHA/RSA pairings. The padding can be easily computed
according to PKCS#1v2.1 as:

  EM = 0x00 || 0x01 || PS || 0x00 || T

where PS is (emLen - tLen - 3) octets of 0xff and T is DER encoding
of the hash.

Store DER prefix in checksum_algo and create rsa_verify_padding
function to handle verification of a message for any SHA/RSA pairing.

Signed-off-by: Andrew Duda <aduda@meraki.com>
Signed-off-by: aduda <aduda@meraki.com>
---

 common/image-sig.c            |   9 ++--
 include/image.h               |   3 +-
 include/u-boot/rsa-checksum.h |   4 --
 include/u-boot/sha1.h         |   3 ++
 include/u-boot/sha256.h       |   3 ++
 lib/rsa/rsa-checksum.c        | 121 ------------------------------------------
 lib/rsa/rsa-verify.c          |  38 ++++++++++++-
 lib/sha1.c                    |   5 ++
 lib/sha256.c                  |   6 +++
 9 files changed, 61 insertions(+), 131 deletions(-)

Comments

Simon Glass Nov. 11, 2016, 4:17 p.m. UTC | #1
On 8 November 2016 at 11:53, aduda <aduda@meraki.com> wrote:
> From: Andrew Duda <aduda@meraki.com>
>
> Padding verification was done against static SHA/RSA pair arrays which
> take up a lot of static memory, are mostly 0xff, and cannot be reused
> for additional SHA/RSA pairings. The padding can be easily computed
> according to PKCS#1v2.1 as:
>
>   EM = 0x00 || 0x01 || PS || 0x00 || T
>
> where PS is (emLen - tLen - 3) octets of 0xff and T is DER encoding
> of the hash.
>
> Store DER prefix in checksum_algo and create rsa_verify_padding
> function to handle verification of a message for any SHA/RSA pairing.
>
> Signed-off-by: Andrew Duda <aduda@meraki.com>
> Signed-off-by: aduda <aduda@meraki.com>
> ---
>
>  common/image-sig.c            |   9 ++--
>  include/image.h               |   3 +-
>  include/u-boot/rsa-checksum.h |   4 --
>  include/u-boot/sha1.h         |   3 ++
>  include/u-boot/sha256.h       |   3 ++
>  lib/rsa/rsa-checksum.c        | 121 ------------------------------------------
>  lib/rsa/rsa-verify.c          |  38 ++++++++++++-
>  lib/sha1.c                    |   5 ++
>  lib/sha256.c                  |   6 +++
>  9 files changed, 61 insertions(+), 131 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

How much memory does this save?
Andrew Duda Nov. 11, 2016, 9:22 p.m. UTC | #2
Simon,

So I looked into this more after you asked this, and it looks very
platform dependent. I tested on two builds: sandbox and a version of
x86-common. The before/after for sandbox image was
5486016-5486800(+784). The before/after for my x86 build was
3306100-3305908(-192). So memory saving is anywhere from a few bytes
to actually more space. But the big motivation is the next two patches
depend on this change.

Thanks,
Andrew

On Fri, Nov 11, 2016 at 8:17 AM, Simon Glass <sjg@chromium.org> wrote:
> On 8 November 2016 at 11:53, aduda <aduda@meraki.com> wrote:
>> From: Andrew Duda <aduda@meraki.com>
>>
>> Padding verification was done against static SHA/RSA pair arrays which
>> take up a lot of static memory, are mostly 0xff, and cannot be reused
>> for additional SHA/RSA pairings. The padding can be easily computed
>> according to PKCS#1v2.1 as:
>>
>>   EM = 0x00 || 0x01 || PS || 0x00 || T
>>
>> where PS is (emLen - tLen - 3) octets of 0xff and T is DER encoding
>> of the hash.
>>
>> Store DER prefix in checksum_algo and create rsa_verify_padding
>> function to handle verification of a message for any SHA/RSA pairing.
>>
>> Signed-off-by: Andrew Duda <aduda@meraki.com>
>> Signed-off-by: aduda <aduda@meraki.com>
>> ---
>>
>>  common/image-sig.c            |   9 ++--
>>  include/image.h               |   3 +-
>>  include/u-boot/rsa-checksum.h |   4 --
>>  include/u-boot/sha1.h         |   3 ++
>>  include/u-boot/sha256.h       |   3 ++
>>  lib/rsa/rsa-checksum.c        | 121 ------------------------------------------
>>  lib/rsa/rsa-verify.c          |  38 ++++++++++++-
>>  lib/sha1.c                    |   5 ++
>>  lib/sha256.c                  |   6 +++
>>  9 files changed, 61 insertions(+), 131 deletions(-)
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> How much memory does this save?
Simon Glass Nov. 14, 2016, 7:04 p.m. UTC | #3
Hi Andrew,

On 11 November 2016 at 14:22, Andrew Duda <andrew.duda@meraki.net> wrote:
> Simon,
>
> So I looked into this more after you asked this, and it looks very
> platform dependent. I tested on two builds: sandbox and a version of
> x86-common. The before/after for sandbox image was
> 5486016-5486800(+784). The before/after for my x86 build was
> 3306100-3305908(-192). So memory saving is anywhere from a few bytes
> to actually more space. But the big motivation is the next two patches
> depend on this change.

OK, well I'm not worried about sandbox, and seeing a saving on a real
x86 board is comforting.

BTW please try not to top-post as it confuses the history.

Regards,
Simon

>
> Thanks,
> Andrew
>
> On Fri, Nov 11, 2016 at 8:17 AM, Simon Glass <sjg@chromium.org> wrote:
>> On 8 November 2016 at 11:53, aduda <aduda@meraki.com> wrote:
>>> From: Andrew Duda <aduda@meraki.com>
>>>
>>> Padding verification was done against static SHA/RSA pair arrays which
>>> take up a lot of static memory, are mostly 0xff, and cannot be reused
>>> for additional SHA/RSA pairings. The padding can be easily computed
>>> according to PKCS#1v2.1 as:
>>>
>>>   EM = 0x00 || 0x01 || PS || 0x00 || T
>>>
>>> where PS is (emLen - tLen - 3) octets of 0xff and T is DER encoding
>>> of the hash.
>>>
>>> Store DER prefix in checksum_algo and create rsa_verify_padding
>>> function to handle verification of a message for any SHA/RSA pairing.
>>>
>>> Signed-off-by: Andrew Duda <aduda@meraki.com>
>>> Signed-off-by: aduda <aduda@meraki.com>
>>> ---
>>>
>>>  common/image-sig.c            |   9 ++--
>>>  include/image.h               |   3 +-
>>>  include/u-boot/rsa-checksum.h |   4 --
>>>  include/u-boot/sha1.h         |   3 ++
>>>  include/u-boot/sha256.h       |   3 ++
>>>  lib/rsa/rsa-checksum.c        | 121 ------------------------------------------
>>>  lib/rsa/rsa-verify.c          |  38 ++++++++++++-
>>>  lib/sha1.c                    |   5 ++
>>>  lib/sha256.c                  |   6 +++
>>>  9 files changed, 61 insertions(+), 131 deletions(-)
>>
>> Reviewed-by: Simon Glass <sjg@chromium.org>
>>
>> How much memory does this save?
Tom Rini Nov. 22, 2016, 2:55 a.m. UTC | #4
On Tue, Nov 08, 2016 at 06:53:40PM +0000, aduda wrote:

> From: Andrew Duda <aduda@meraki.com>
> 
> Padding verification was done against static SHA/RSA pair arrays which
> take up a lot of static memory, are mostly 0xff, and cannot be reused
> for additional SHA/RSA pairings. The padding can be easily computed
> according to PKCS#1v2.1 as:
> 
>   EM = 0x00 || 0x01 || PS || 0x00 || T
> 
> where PS is (emLen - tLen - 3) octets of 0xff and T is DER encoding
> of the hash.
> 
> Store DER prefix in checksum_algo and create rsa_verify_padding
> function to handle verification of a message for any SHA/RSA pairing.
> 
> Signed-off-by: Andrew Duda <aduda@meraki.com>
> Signed-off-by: aduda <aduda@meraki.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>

Applied to u-boot/master, thanks!
diff mbox

Patch

diff --git a/common/image-sig.c b/common/image-sig.c
index 28f7a20..008d2c5 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -34,32 +34,35 @@  struct checksum_algo checksum_algos[] = {
 	{
 		"sha1",
 		SHA1_SUM_LEN,
+		SHA1_DER_LEN,
+		sha1_der_prefix,
 		RSA2048_BYTES,
 #if IMAGE_ENABLE_SIGN
 		EVP_sha1,
 #endif
 		hash_calculate,
-		padding_sha1_rsa2048,
 	},
 	{
 		"sha256",
 		SHA256_SUM_LEN,
+		SHA256_DER_LEN,
+		sha256_der_prefix,
 		RSA2048_BYTES,
 #if IMAGE_ENABLE_SIGN
 		EVP_sha256,
 #endif
 		hash_calculate,
-		padding_sha256_rsa2048,
 	},
 	{
 		"sha256",
 		SHA256_SUM_LEN,
+		SHA256_DER_LEN,
+		sha256_der_prefix,
 		RSA4096_BYTES,
 #if IMAGE_ENABLE_SIGN
 		EVP_sha256,
 #endif
 		hash_calculate,
-		padding_sha256_rsa4096,
 	}
 
 };
diff --git a/include/image.h b/include/image.h
index bfe10a0..de73a07 100644
--- a/include/image.h
+++ b/include/image.h
@@ -1070,6 +1070,8 @@  struct image_region {
 struct checksum_algo {
 	const char *name;
 	const int checksum_len;
+	const int der_len;
+	const uint8_t *der_prefix;
 	const int key_len;
 #if IMAGE_ENABLE_SIGN
 	const EVP_MD *(*calculate_sign)(void);
@@ -1077,7 +1079,6 @@  struct checksum_algo {
 	int (*calculate)(const char *name,
 			 const struct image_region region[],
 			 int region_count, uint8_t *checksum);
-	const uint8_t *rsa_padding;
 };
 
 struct image_sig_algo {
diff --git a/include/u-boot/rsa-checksum.h b/include/u-boot/rsa-checksum.h
index 3c69d85..c240720 100644
--- a/include/u-boot/rsa-checksum.h
+++ b/include/u-boot/rsa-checksum.h
@@ -12,10 +12,6 @@ 
 #include <u-boot/sha1.h>
 #include <u-boot/sha256.h>
 
-extern const uint8_t padding_sha256_rsa4096[];
-extern const uint8_t padding_sha256_rsa2048[];
-extern const uint8_t padding_sha1_rsa2048[];
-
 /**
  * hash_calculate() - Calculate hash over the data
  *
diff --git a/include/u-boot/sha1.h b/include/u-boot/sha1.h
index b0d9ce9..2634a29 100644
--- a/include/u-boot/sha1.h
+++ b/include/u-boot/sha1.h
@@ -21,6 +21,9 @@  extern "C" {
 
 #define SHA1_SUM_POS	-0x20
 #define SHA1_SUM_LEN	20
+#define SHA1_DER_LEN	15
+
+extern const uint8_t sha1_der_prefix[];
 
 /**
  * \brief	   SHA-1 context structure
diff --git a/include/u-boot/sha256.h b/include/u-boot/sha256.h
index beadab3..9aa1251 100644
--- a/include/u-boot/sha256.h
+++ b/include/u-boot/sha256.h
@@ -2,6 +2,9 @@ 
 #define _SHA256_H
 
 #define SHA256_SUM_LEN	32
+#define SHA256_DER_LEN	19
+
+extern const uint8_t sha256_der_prefix[];
 
 /* Reset watchdog each time we process this many bytes */
 #define CHUNKSZ_SHA256	(64 * 1024)
diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
index db183ff..2bf28e2 100644
--- a/lib/rsa/rsa-checksum.c
+++ b/lib/rsa/rsa-checksum.c
@@ -13,130 +13,9 @@ 
 #include <hash.h>
 #else
 #include "fdt_host.h"
-#include <u-boot/sha1.h>
-#include <u-boot/sha256.h>
 #endif
 #include <u-boot/rsa.h>
 
-/* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
-
-const uint8_t padding_sha256_rsa2048[RSA2048_BYTES - SHA256_SUM_LEN] = {
-0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
-0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
-0x00, 0x04, 0x20
-};
-
-const uint8_t padding_sha1_rsa2048[RSA2048_BYTES - SHA1_SUM_LEN] = {
-	0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x21, 0x30,
-	0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a,
-	0x05, 0x00, 0x04, 0x14
-};
-
-const uint8_t padding_sha256_rsa4096[RSA4096_BYTES - SHA256_SUM_LEN] = {
-	0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	0xff, 0xff, 0xff, 0xff, 0x00, 0x30, 0x31, 0x30,
-	0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65,
-	0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
-};
-
 int hash_calculate(const char *name,
 		    const struct image_region region[],
 		    int region_count, uint8_t *checksum)
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 5418f59..ee8988d 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -25,6 +25,40 @@ 
 #define RSA_DEFAULT_PUBEXP	65537
 
 /**
+ * rsa_verify_padding() - Verify RSA message padding is valid
+ *
+ * Verify a RSA message's padding is consistent with PKCS1.5
+ * padding as described in the RSA PKCS#1 v2.1 standard.
+ *
+ * @msg:	Padded message
+ * @pad_len:	Number of expected padding bytes
+ * @algo:	Checksum algo structure having information on DER encoding etc.
+ * @return 0 on success, != 0 on failure
+ */
+static int rsa_verify_padding(const uint8_t *msg, const int pad_len,
+			      struct checksum_algo *algo)
+{
+	int ff_len;
+	int ret;
+
+	/* first byte must be 0x00 */
+	ret = *msg++;
+	/* second byte must be 0x01 */
+	ret |= *msg++ ^ 0x01;
+	/* next ff_len bytes must be 0xff */
+	ff_len = pad_len - algo->der_len - 3;
+	ret |= *msg ^ 0xff;
+	ret |= memcmp(msg, msg+1, ff_len-1);
+	msg += ff_len;
+	/* next byte must be 0x00 */
+	ret |= *msg++;
+	/* next der_len bytes must match der_prefix */
+	ret |= memcmp(msg, algo->der_prefix, algo->der_len);
+
+	return ret;
+}
+
+/**
  * rsa_verify_key() - Verify a signature against some data using RSA Key
  *
  * Verify a RSA PKCS1.5 signature against an expected hash using
@@ -83,11 +117,11 @@  static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
 		return ret;
 	}
 
-	padding = algo->rsa_padding;
 	pad_len = algo->key_len - algo->checksum_len;
 
 	/* Check pkcs1.5 padding bytes. */
-	if (memcmp(buf, padding, pad_len)) {
+	ret = rsa_verify_padding(buf, pad_len, algo);
+	if (ret) {
 		debug("In RSAVerify(): Padding check failed!\n");
 		return -EINVAL;
 	}
diff --git a/lib/sha1.c b/lib/sha1.c
index 72c5dea..f54bb5b 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -26,6 +26,11 @@ 
 #include <watchdog.h>
 #include <u-boot/sha1.h>
 
+const uint8_t sha1_der_prefix[SHA1_DER_LEN] = {
+	0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e,
+	0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
+};
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */
diff --git a/lib/sha256.c b/lib/sha256.c
index bb338ba..7f5a361 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -15,6 +15,12 @@ 
 #include <watchdog.h>
 #include <u-boot/sha256.h>
 
+const uint8_t sha256_der_prefix[SHA256_DER_LEN] = {
+	0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+	0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+	0x00, 0x04, 0x20
+};
+
 /*
  * 32-bit integer manipulation macros (big endian)
  */