summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/2lib/2rsa.c88
-rw-r--r--firmware/2lib/2sha_utility.c3
-rw-r--r--firmware/2lib/include/2crypto.h5
-rw-r--r--futility/file_type_usbpd1.c2
-rw-r--r--host/lib21/host_key.c34
-rw-r--r--tests/common.sh2
-rwxr-xr-xtests/futility/test_show_rwsig.sh2
-rwxr-xr-xtests/gen_test_keys.sh10
-rw-r--r--tests/testcases/test_file.rsa2048_exp3_sha1.sigbin0 -> 256 bytes
-rw-r--r--tests/testcases/test_file.rsa2048_exp3_sha256.sig2
-rw-r--r--tests/testcases/test_file.rsa2048_exp3_sha512.sigbin0 -> 256 bytes
-rw-r--r--tests/testkeys/key_rsa2048_exp3.crt20
-rw-r--r--tests/testkeys/key_rsa2048_exp3.keybbin0 -> 520 bytes
-rw-r--r--tests/testkeys/key_rsa2048_exp3.pem27
-rw-r--r--tests/testkeys/key_rsa2048_exp3.sha1.vbprivkbin0 -> 1200 bytes
-rw-r--r--tests/testkeys/key_rsa2048_exp3.sha1.vbpubkbin0 -> 552 bytes
-rw-r--r--tests/testkeys/key_rsa2048_exp3.sha256.vbprivkbin0 -> 1200 bytes
-rw-r--r--tests/testkeys/key_rsa2048_exp3.sha256.vbpubkbin0 -> 552 bytes
-rw-r--r--tests/testkeys/key_rsa2048_exp3.sha512.vbprivkbin0 -> 1200 bytes
-rw-r--r--tests/testkeys/key_rsa2048_exp3.sha512.vbpubkbin0 -> 552 bytes
-rw-r--r--utility/dumpRSAPublicKey.c5
21 files changed, 174 insertions, 26 deletions
diff --git a/firmware/2lib/2rsa.c b/firmware/2lib/2rsa.c
index 7862b133..48e1ec33 100644
--- a/firmware/2lib/2rsa.c
+++ b/firmware/2lib/2rsa.c
@@ -73,6 +73,25 @@ static void montMulAdd(const struct vb2_public_key *key,
}
/**
+ * Montgomery c[] += 0 * b[] / R % mod
+ */
+static void montMulAdd0(const struct vb2_public_key *key,
+ uint32_t *c,
+ const uint32_t *b)
+{
+ uint32_t d0 = c[0] * key->n0inv;
+ uint64_t B = (uint64_t)d0 * key->n[0] + c[0];
+ uint32_t i;
+
+ for (i = 1; i < key->arrsize; ++i) {
+ B = (B >> 32) + (uint64_t)d0 * key->n[i] + c[i];
+ c[i - 1] = (uint32_t)B;
+ }
+
+ c[i - 1] = B >> 32;
+}
+
+/**
* Montgomery c[] = a[] * b[] / R % mod
*/
static void montMul(const struct vb2_public_key *key,
@@ -89,16 +108,32 @@ static void montMul(const struct vb2_public_key *key,
}
}
+/* Montgomery c[] = a[] * 1 / R % key. */
+static void montMul1(const struct vb2_public_key *key,
+ uint32_t *c,
+ const uint32_t *a)
+{
+ int i;
+
+ for (i = 0; i < key->arrsize; ++i)
+ c[i] = 0;
+
+ montMulAdd(key, c, 1, a);
+ for (i = 1; i < key->arrsize; ++i)
+ montMulAdd0(key, c, a);
+}
+
/**
- * In-place public exponentiation. (65537}
+ * In-place public exponentiation.
*
* @param key Key to use in signing
* @param inout Input and output big-endian byte array
* @param workbuf32 Work buffer; caller must verify this is
* (3 * key->arrsize) elements long.
+ * @param exp RSA public exponent: either 65537 (F4) or 3
*/
-static void modpowF4(const struct vb2_public_key *key, uint8_t *inout,
- uint32_t *workbuf32)
+static void modpow(const struct vb2_public_key *key, uint8_t *inout,
+ uint32_t *workbuf32, int exp)
{
uint32_t *a = workbuf32;
uint32_t *aR = a + key->arrsize;
@@ -117,12 +152,18 @@ static void modpowF4(const struct vb2_public_key *key, uint8_t *inout,
}
montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */
- for (i = 0; i < 16; i+=2) {
- montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */
- montMul(key, aR, aaR, aaR); /* aR = aaR * aaR / R mod M */
+ if (exp == 3) {
+ montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */
+ montMul(key, a, aaR, aR); /* a = aaR * aR / R mod M */
+ montMul1(key, aaa, a); /* aaa = a * 1 / R mod M */
+ } else {
+ /* Exponent 65537 */
+ for (i = 0; i < 16; i+=2) {
+ montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */
+ montMul(key, aR, aaR, aaR); /* aR = aaR * aaR / R mod M */
+ }
+ montMul(key, aaa, aR, a); /* aaa = aR * a / R mod M */
}
- montMul(key, aaa, aR, a); /* aaa = aR * a / R mod M */
-
/* Make sure aaa < mod; aaa is at most 1x mod too large. */
if (vb2_mont_ge(key, aaa)) {
@@ -153,6 +194,9 @@ static const uint8_t crypto_to_sig[] = {
VB2_SIG_RSA8192,
VB2_SIG_RSA8192,
VB2_SIG_RSA8192,
+ VB2_SIG_RSA2048_EXP3,
+ VB2_SIG_RSA2048_EXP3,
+ VB2_SIG_RSA2048_EXP3,
};
/**
@@ -178,6 +222,7 @@ uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
case VB2_SIG_RSA1024:
return 1024 / 8;
case VB2_SIG_RSA2048:
+ case VB2_SIG_RSA2048_EXP3:
return 2048 / 8;
case VB2_SIG_RSA4096:
return 4096 / 8;
@@ -188,6 +233,27 @@ uint32_t vb2_rsa_sig_size(enum vb2_signature_algorithm sig_alg)
}
}
+/**
+ * Return the exponent used by an RSA algorithm
+ *
+ * @param sig_alg Signature algorithm
+ * @return The exponent to use (3 or 65537(F4)), or 0 if error.
+ */
+static uint32_t vb2_rsa_exponent(enum vb2_signature_algorithm sig_alg)
+{
+ switch (sig_alg) {
+ case VB2_SIG_RSA1024:
+ case VB2_SIG_RSA2048:
+ case VB2_SIG_RSA4096:
+ case VB2_SIG_RSA8192:
+ return 65537;
+ case VB2_SIG_RSA2048_EXP3:
+ return 3;
+ default:
+ return 0;
+ }
+}
+
uint32_t vb2_packed_key_size(enum vb2_signature_algorithm sig_alg)
{
uint32_t sig_size = vb2_rsa_sig_size(sig_alg);
@@ -298,13 +364,15 @@ int vb2_rsa_verify_digest(const struct vb2_public_key *key,
uint32_t key_bytes;
int sig_size;
int pad_size;
+ int exp;
int rv;
if (!key || !sig || !digest)
return VB2_ERROR_RSA_VERIFY_PARAM;
sig_size = vb2_rsa_sig_size(key->sig_alg);
- if (!sig_size) {
+ exp = vb2_rsa_exponent(key->sig_alg);
+ if (!sig_size || !exp) {
VB2_DEBUG("Invalid signature type!\n");
return VB2_ERROR_RSA_VERIFY_ALGORITHM;
}
@@ -322,7 +390,7 @@ int vb2_rsa_verify_digest(const struct vb2_public_key *key,
return VB2_ERROR_RSA_VERIFY_WORKBUF;
}
- modpowF4(key, sig, workbuf32);
+ modpow(key, sig, workbuf32, exp);
vb2_workbuf_free(&wblocal, 3 * key_bytes);
diff --git a/firmware/2lib/2sha_utility.c b/firmware/2lib/2sha_utility.c
index dd74f290..7193091b 100644
--- a/firmware/2lib/2sha_utility.c
+++ b/firmware/2lib/2sha_utility.c
@@ -40,6 +40,9 @@ static const uint8_t crypto_to_hash[] = {
CTH_SHA1,
CTH_SHA256,
CTH_SHA512,
+ CTH_SHA1,
+ CTH_SHA256,
+ CTH_SHA512,
};
enum vb2_hash_algorithm vb2_crypto_to_hash(uint32_t algorithm)
diff --git a/firmware/2lib/include/2crypto.h b/firmware/2lib/include/2crypto.h
index da1c2ddf..a33b5360 100644
--- a/firmware/2lib/include/2crypto.h
+++ b/firmware/2lib/include/2crypto.h
@@ -23,7 +23,9 @@ enum vb2_crypto_algorithm {
VB2_ALG_RSA8192_SHA1 = 9,
VB2_ALG_RSA8192_SHA256 = 10,
VB2_ALG_RSA8192_SHA512 = 11,
-
+ VB2_ALG_RSA2048_EXP3_SHA1 = 12,
+ VB2_ALG_RSA2048_EXP3_SHA256 = 13,
+ VB2_ALG_RSA2048_EXP3_SHA512 = 14,
/* Number of algorithms */
VB2_ALG_COUNT
};
@@ -44,6 +46,7 @@ enum vb2_signature_algorithm {
VB2_SIG_RSA2048 = 3,
VB2_SIG_RSA4096 = 4,
VB2_SIG_RSA8192 = 5,
+ VB2_SIG_RSA2048_EXP3 = 6,
/* Last index. Don't add anything below. */
VB2_SIG_ALG_COUNT,
diff --git a/futility/file_type_usbpd1.c b/futility/file_type_usbpd1.c
index 81430855..131e0033 100644
--- a/futility/file_type_usbpd1.c
+++ b/futility/file_type_usbpd1.c
@@ -256,6 +256,7 @@ done:
*/
static enum vb2_signature_algorithm sigs[] = {
VB2_SIG_RSA2048,
+ VB2_SIG_RSA2048_EXP3,
VB2_SIG_RSA1024,
VB2_SIG_RSA4096,
VB2_SIG_RSA8192,
@@ -277,6 +278,7 @@ static uint32_t usbpd1_packed_key_size(enum vb2_signature_algorithm sig_alg)
case VB2_SIG_RSA1024:
return 272;
case VB2_SIG_RSA2048:
+ case VB2_SIG_RSA2048_EXP3:
return 528;
case VB2_SIG_RSA4096:
return 1040;
diff --git a/host/lib21/host_key.c b/host/lib21/host_key.c
index ecb7328b..be36df71 100644
--- a/host/lib21/host_key.c
+++ b/host/lib21/host_key.c
@@ -23,6 +23,7 @@ const struct vb2_text_vs_enum vb2_text_vs_sig[] = {
{"RSA2048", VB2_SIG_RSA2048},
{"RSA4096", VB2_SIG_RSA4096},
{"RSA8192", VB2_SIG_RSA8192},
+ {"RSA2048EXP3", VB2_SIG_RSA2048_EXP3},
{0, 0}
};
@@ -403,7 +404,10 @@ int vb2_public_key_read_keyb(struct vb2_public_key **key_ptr,
if (vb2_read_file(filename, &key_data, &key_size))
return VB2_ERROR_READ_KEYB_DATA;
- /* Guess the signature algorithm from the key size */
+ /* Guess the signature algorithm from the key size
+ * Note: This only considers exponent F4 keys, as there is no way to
+ * distinguish between exp 3 and F4 based on size. Vboot API 2.1 is
+ * required to make proper use of exp 3 keys. */
for (sig_alg = VB2_SIG_RSA1024; sig_alg <= VB2_SIG_RSA8192; sig_alg++) {
if (key_size == vb2_packed_key_size(sig_alg))
break;
@@ -560,17 +564,27 @@ int vb2_public_key_hash(struct vb2_public_key *key,
enum vb2_signature_algorithm vb2_rsa_sig_alg(struct rsa_st *rsa)
{
+ int exp = BN_get_word(rsa->e);
int bits = BN_num_bits(rsa->n);
- switch (bits) {
- case 1024:
- return VB2_SIG_RSA1024;
- case 2048:
- return VB2_SIG_RSA2048;
- case 4096:
- return VB2_SIG_RSA4096;
- case 8192:
- return VB2_SIG_RSA8192;
+ switch (exp) {
+ case RSA_3:
+ switch (bits) {
+ case 2048:
+ return VB2_SIG_RSA2048_EXP3;
+ }
+ break;
+ case RSA_F4:
+ switch (bits) {
+ case 1024:
+ return VB2_SIG_RSA1024;
+ case 2048:
+ return VB2_SIG_RSA2048;
+ case 4096:
+ return VB2_SIG_RSA4096;
+ case 8192:
+ return VB2_SIG_RSA8192;
+ }
}
/* no clue */
diff --git a/tests/common.sh b/tests/common.sh
index 2b017cc5..78a47fa8 100644
--- a/tests/common.sh
+++ b/tests/common.sh
@@ -28,7 +28,7 @@ COL_BLUE='\E[34;1m'
COL_STOP='\E[0;m'
hash_algos=( sha1 sha256 sha512 )
-key_lengths=( 1024 2048 4096 8192 )
+key_lengths=( 1024 2048 4096 8192 2048_exp3 )
function happy {
echo -e "${COL_GREEN}$*${COL_STOP}" 1>&2
diff --git a/tests/futility/test_show_rwsig.sh b/tests/futility/test_show_rwsig.sh
index 7ff25571..915842d6 100755
--- a/tests/futility/test_show_rwsig.sh
+++ b/tests/futility/test_show_rwsig.sh
@@ -13,7 +13,7 @@ DATADIR="${SCRIPTDIR}/data"
TESTKEYS=${SRCDIR}/tests/testkeys
# Do not test 8192 as the signature length is > 1024 bytes
-SIGS="1024 2048 4096"
+SIGS="1024 2048 4096 2048_exp3"
HASHES="SHA1 SHA256 SHA512"
set -o pipefail
diff --git a/tests/gen_test_keys.sh b/tests/gen_test_keys.sh
index dbb17419..04315ac3 100755
--- a/tests/gen_test_keys.sh
+++ b/tests/gen_test_keys.sh
@@ -25,7 +25,15 @@ function generate_keys {
continue
fi
- openssl genrsa -F4 -out ${key_base}.pem $i
+ # Extract exponent from key_length name, if necessary
+ exp="F4"
+ bits=$i
+ if [ "${i##*_exp}" != "${i}" ]; then
+ exp="${i##*_exp}"
+ bits="${i%%_exp${exp}}"
+ fi
+
+ openssl genrsa -${exp} -out ${key_base}.pem ${bits}
# Generate self-signed certificate from key.
openssl req -batch -new -x509 -key ${key_base}.pem \
-out ${key_base}.crt
diff --git a/tests/testcases/test_file.rsa2048_exp3_sha1.sig b/tests/testcases/test_file.rsa2048_exp3_sha1.sig
new file mode 100644
index 00000000..75cd3ba4
--- /dev/null
+++ b/tests/testcases/test_file.rsa2048_exp3_sha1.sig
Binary files differ
diff --git a/tests/testcases/test_file.rsa2048_exp3_sha256.sig b/tests/testcases/test_file.rsa2048_exp3_sha256.sig
new file mode 100644
index 00000000..1192c8e3
--- /dev/null
+++ b/tests/testcases/test_file.rsa2048_exp3_sha256.sig
@@ -0,0 +1,2 @@
+ _#ٌ%:a ollnLNAUʩu4y ѷ_02mԩ*a.Ъa-f@9+"+|+YxH4~ƛVW<vO5:@8bp'XzLLQ4
+J~6 iQC9]Sa qOnl_x-inuyzKi2|xԂIVg=ݬ~Gΰ^ u7TȘ =Kk,%* \ No newline at end of file
diff --git a/tests/testcases/test_file.rsa2048_exp3_sha512.sig b/tests/testcases/test_file.rsa2048_exp3_sha512.sig
new file mode 100644
index 00000000..155474a1
--- /dev/null
+++ b/tests/testcases/test_file.rsa2048_exp3_sha512.sig
Binary files differ
diff --git a/tests/testkeys/key_rsa2048_exp3.crt b/tests/testkeys/key_rsa2048_exp3.crt
new file mode 100644
index 00000000..1c88aea8
--- /dev/null
+++ b/tests/testkeys/key_rsa2048_exp3.crt
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDWzCCAkOgAwIBAgIJAO+pvxf/+8DVMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTcwMjA3MDgzNTQ5WhcNMTcwMzA5MDgzNTQ5WjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIB
+CAKCAQEA3UvKSmYs87zzCjmpwlSJlOdsoz+7JFekYTbUizUwf+k20mz9d042zL3X
+PFenwKsNwrqS0+iJ+zwLMXmDG5+Jnh/4k1xCpjz9gAoIuTHYSR+nFfvJBocdZhiX
+LAZW1RSbqYaZJn67JR4GgajrmhJkk1nOhY1y4kPqEwuVbWFX5V50ZiDta0iqUyph
+ADb3Z0xBRS6SjRJAtyV2KiR6oi15qnKCD9rxIOtWAUMUjmhZeSpxUS4+iPsEh7j4
+oKlMys7Ty2NXxxo12f6orz0vJn3zcaj2XFgQZNZF56W5N5VjXIiDPNYoNArDICXm
+BhhtAYRh+tGGsUotNKiC4k4hufEvVQIBA6NQME4wHQYDVR0OBBYEFHfxG/+7G+zh
+jH4d8VpC/dnCXTN0MB8GA1UdIwQYMBaAFHfxG/+7G+zhjH4d8VpC/dnCXTN0MAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAMJe2ClDV+DeQudWz++yTLUz
+qgn6XHSgPv/jgyWXxEcguh6G4GXuCgEykkJ2l4Zyb9+0QurOa4/cDv1Vu54p60ZF
+OhQyX0YFNTXIXJkuFy2KEClSpQ0yglrFaPzBmpmJY4LMR2Dbxze/f+i94HaeQDFd
+Sze8VyJxnqagBNX6QgxWEhUvIs/OVwkkJ2ZoK7JkhX9gDzxUZ01EvFkoszQNxDgy
+ETFxBf/pbZspKiyOVoWCm4OzKXIAqRqWX1Gg2BFUdxLof6XbD/F96xcsUgZkTBuu
+thBMQrCxGwmbZhwnfoZ0PgcagCdqlLkUUsOJuj4AGDK+4X8Rdzlc5wbjPBAgt9U=
+-----END CERTIFICATE-----
diff --git a/tests/testkeys/key_rsa2048_exp3.keyb b/tests/testkeys/key_rsa2048_exp3.keyb
new file mode 100644
index 00000000..3f8c5645
--- /dev/null
+++ b/tests/testkeys/key_rsa2048_exp3.keyb
Binary files differ
diff --git a/tests/testkeys/key_rsa2048_exp3.pem b/tests/testkeys/key_rsa2048_exp3.pem
new file mode 100644
index 00000000..ca3127c0
--- /dev/null
+++ b/tests/testkeys/key_rsa2048_exp3.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA3UvKSmYs87zzCjmpwlSJlOdsoz+7JFekYTbUizUwf+k20mz9
+d042zL3XPFenwKsNwrqS0+iJ+zwLMXmDG5+Jnh/4k1xCpjz9gAoIuTHYSR+nFfvJ
+BocdZhiXLAZW1RSbqYaZJn67JR4GgajrmhJkk1nOhY1y4kPqEwuVbWFX5V50ZiDt
+a0iqUyphADb3Z0xBRS6SjRJAtyV2KiR6oi15qnKCD9rxIOtWAUMUjmhZeSpxUS4+
+iPsEh7j4oKlMys7Ty2NXxxo12f6orz0vJn3zcaj2XFgQZNZF56W5N5VjXIiDPNYo
+NArDICXmBhhtAYRh+tGGsUotNKiC4k4hufEvVQIBAwKCAQEAk4fcMZlzTSiiBtEb
+1uMGY0TzF3/SGDptliSNsiN1qpt54Z3+T4l53dPk0uUagHIJLHxh4psGp31cy6ZX
+Z7+xFBVQYj2BxCipAAawe3aQML/EuVKGBFoTmWW6HVmPOLhnxlm7bv8nbhQEVnCd
+EWGYYjvfA7Oh7C1Gt10OSOuP7j26NRur2gNita/MT2FCKxQ6Dnu2lkTc9I5XkP2+
+v7BhLG/zkwvOcGeXtSbmAXXh5ON/igSe0WZvMKj0ql+f8S7vnevoDOFIeHm7diCO
+Ej0fWavFMAPOZokBzQycSuQ0awrV8gM4xMpahBjwRcC3UMoNLmlvo8kcbkxJ0Sbv
+AcLMMwKBgQD+ZjSJyf6Or48fyOlWG0/do1mpJogoawyOK5mF3Z7O6wVm+DMpXQsE
+ApIZzblMajmZQcvZ/AR+/mDV2s34x6WGFkR7GMIHHoaIuA3Qk6jm/qFdgcAmumHU
+vtrGDX+votDfBeoIb+bWCRjjD3SeEpoNjy/1DYNQmYkRQ0zIJZ9QUwKBgQDesELh
+2kUHkxOOwDu+C14MjBtXhSLM3UNkpQ5WpQYY/MUtuxYSG0Tubvahvn46N5uYwFt2
+UtzewFqzxkvkGWLmSD0AmwZCBsGGxf6Jd3ldbIXxEpI0EKbudTgIub9lGSdjS+dK
+nPRlUOeajgK79btApgNqLhkx9a0C5UbzEa2stwKBgQCpmXhb2/8Jyl9qhfDkEjU+
+bOZwxFrFnLMJcmZZPmnfR1jvUCIbk1ytVwwRM9DdnCZmK907/VhUqZXj5zP7L8Ou
+uYL8uywEvwRbJV6LDRtEqcDpASrEfEE4fzyECP/KbIs/WUawSpnkBhCXX6MUDGaz
+tMqjXleLEQYLgjMwGRTgNwKBgQCUdYHr5tivt2JfKtJ+sj6zCBI6WMHd6NeYbgmP
+GK67Uy4efLlhZ4NJn08Wfv7Reme7KuekNz3p1ZHNLt1Cu5dEMCirEgQsBIEEg/8G
+T6Y+SFlLYbbNYG9Jo3qwe9TuEMTs3UTcaKLuNe+8Xqx9TnzVxAJGyWYhTnNXQ4Si
+C8kdzwKBgQCmfbKHyzXa0E1dFQKU59hXBhSKBp6ZvD/pF5Ed4tZW0ubdCVs7665p
+cdi5ljpJsjqHzWTn8TLdbXZ2jYPPNTC89wZ8F1lrPHCYz/Ifnoahlcbp7OIiIcWx
+S6YTzuFdpxAAdwstY91LMxzzMZm47hZUw/KzEVfzIpdyLbeCouohzg==
+-----END RSA PRIVATE KEY-----
diff --git a/tests/testkeys/key_rsa2048_exp3.sha1.vbprivk b/tests/testkeys/key_rsa2048_exp3.sha1.vbprivk
new file mode 100644
index 00000000..357a53a7
--- /dev/null
+++ b/tests/testkeys/key_rsa2048_exp3.sha1.vbprivk
Binary files differ
diff --git a/tests/testkeys/key_rsa2048_exp3.sha1.vbpubk b/tests/testkeys/key_rsa2048_exp3.sha1.vbpubk
new file mode 100644
index 00000000..8f17ce92
--- /dev/null
+++ b/tests/testkeys/key_rsa2048_exp3.sha1.vbpubk
Binary files differ
diff --git a/tests/testkeys/key_rsa2048_exp3.sha256.vbprivk b/tests/testkeys/key_rsa2048_exp3.sha256.vbprivk
new file mode 100644
index 00000000..eb10c73c
--- /dev/null
+++ b/tests/testkeys/key_rsa2048_exp3.sha256.vbprivk
Binary files differ
diff --git a/tests/testkeys/key_rsa2048_exp3.sha256.vbpubk b/tests/testkeys/key_rsa2048_exp3.sha256.vbpubk
new file mode 100644
index 00000000..70bfcf6e
--- /dev/null
+++ b/tests/testkeys/key_rsa2048_exp3.sha256.vbpubk
Binary files differ
diff --git a/tests/testkeys/key_rsa2048_exp3.sha512.vbprivk b/tests/testkeys/key_rsa2048_exp3.sha512.vbprivk
new file mode 100644
index 00000000..0e1f862c
--- /dev/null
+++ b/tests/testkeys/key_rsa2048_exp3.sha512.vbprivk
Binary files differ
diff --git a/tests/testkeys/key_rsa2048_exp3.sha512.vbpubk b/tests/testkeys/key_rsa2048_exp3.sha512.vbpubk
new file mode 100644
index 00000000..429d2c3d
--- /dev/null
+++ b/tests/testkeys/key_rsa2048_exp3.sha512.vbpubk
Binary files differ
diff --git a/utility/dumpRSAPublicKey.c b/utility/dumpRSAPublicKey.c
index b3b7b96b..fc238d7f 100644
--- a/utility/dumpRSAPublicKey.c
+++ b/utility/dumpRSAPublicKey.c
@@ -23,8 +23,9 @@ int check(RSA* key) {
int public_exponent = BN_get_word(key->e);
int modulus = BN_num_bits(key->n);
- if (public_exponent != 65537) {
- fprintf(stderr, "WARNING: Public exponent should be 65537 (but is %d).\n",
+ if (public_exponent != 3 && public_exponent != 65537) {
+ fprintf(stderr,
+ "WARNING: Public exponent should be 3 or 65537 (but is %d).\n",
public_exponent);
}