summaryrefslogtreecommitdiffstats
path: root/libmincrypt/rsa_e_f4.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmincrypt/rsa_e_f4.c')
-rw-r--r--libmincrypt/rsa_e_f4.c79
1 files changed, 71 insertions, 8 deletions
diff --git a/libmincrypt/rsa_e_f4.c b/libmincrypt/rsa_e_f4.c
index 6701bcc..17a2de2 100644
--- a/libmincrypt/rsa_e_f4.c
+++ b/libmincrypt/rsa_e_f4.c
@@ -27,6 +27,7 @@
#include "mincrypt/rsa.h"
#include "mincrypt/sha.h"
+#include "mincrypt/sha256.h"
// a[] -= mod
static void subM(const RSAPublicKey* key,
@@ -138,26 +139,79 @@ static void modpowF4(const RSAPublicKey* key,
// other flavor which omits the optional parameter entirely). This code does not
// accept signatures without the optional parameter.
/*
-static const uint8_t padding[RSANUMBYTES] = {
+static const uint8_t sha_padding[RSANUMBYTES] = {
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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
+
+static const uint8_t sha256_padding[RSANUMBYTES] = {
+ 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,
+
+ // 32 bytes of hash go here.
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,
+};
+
*/
-// SHA-1 of PKCS1.5 signature padding for 2048 bit, as above.
+// SHA-1 of PKCS1.5 signature sha_padding for 2048 bit, as above.
// At the location of the bytes of the hash all 00 are hashed.
static const uint8_t kExpectedPadShaRsa2048[SHA_DIGEST_SIZE] = {
0xdc, 0xbd, 0xbe, 0x42, 0xd5, 0xf5, 0xa7, 0x2e, 0x6e, 0xfc,
0xf5, 0x5d, 0xaf, 0x9d, 0xea, 0x68, 0x7c, 0xfb, 0xf1, 0x67
};
+// SHA-256 of PKCS1.5 signature sha256_padding for 2048 bit, as above.
+// At the location of the bytes of the hash all 00 are hashed.
+static const uint8_t kExpectedPadSha256Rsa2048[SHA256_DIGEST_SIZE] = {
+ 0xab, 0x28, 0x8d, 0x8a, 0xd7, 0xd9, 0x59, 0x92,
+ 0xba, 0xcc, 0xf8, 0x67, 0x20, 0xe1, 0x15, 0x2e,
+ 0x39, 0x8d, 0x80, 0x36, 0xd6, 0x6f, 0xf0, 0xfd,
+ 0x90, 0xe8, 0x7d, 0x8b, 0xe1, 0x7c, 0x87, 0x59,
+};
+
// Verify a 2048 bit RSA e=65537 PKCS1.5 signature against an expected
// SHA-1 hash. Returns 0 on failure, 1 on success.
int RSA_e_f4_verify(const RSAPublicKey* key,
const uint8_t* signature,
const int len,
- const uint8_t* sha) {
+ const uint8_t* hash,
+ const int hash_len) {
uint8_t buf[RSANUMBYTES];
int i;
+ const uint8_t* padding_hash;
+
+ switch (hash_len) {
+ case SHA_DIGEST_SIZE:
+ padding_hash = kExpectedPadShaRsa2048;
+ break;
+ case SHA256_DIGEST_SIZE:
+ padding_hash = kExpectedPadSha256Rsa2048;
+ break;
+ default:
+ return 0; // unsupported hash
+ }
if (key->len != RSANUMWORDS) {
return 0; // Wrong key passed in.
@@ -178,16 +232,25 @@ int RSA_e_f4_verify(const RSAPublicKey* key,
modpowF4(key, buf); // In-place exponentiation.
// Xor sha portion, so it all becomes 00 iff equal.
- for (i = len - SHA_DIGEST_SIZE; i < len; ++i) {
- buf[i] ^= *sha++;
+ for (i = len - hash_len; i < len; ++i) {
+ buf[i] ^= *hash++;
}
// Hash resulting buf, in-place.
- SHA(buf, len, buf);
+ switch (hash_len) {
+ case SHA_DIGEST_SIZE:
+ SHA_hash(buf, len, buf);
+ break;
+ case SHA256_DIGEST_SIZE:
+ SHA256_hash(buf, len, buf);
+ break;
+ default:
+ return 0;
+ }
// Compare against expected hash value.
- for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
- if (buf[i] != kExpectedPadShaRsa2048[i]) {
+ for (i = 0; i < hash_len; ++i) {
+ if (buf[i] != padding_hash[i]) {
return 0;
}
}