summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/2lib/2rsa.c19
-rw-r--r--firmware/2lib/2stub_hwcrypto.c5
-rw-r--r--firmware/2lib/include/2api.h14
-rw-r--r--tests/vb20_rsa_padding_tests.c22
4 files changed, 58 insertions, 2 deletions
diff --git a/firmware/2lib/2rsa.c b/firmware/2lib/2rsa.c
index 1a23d023..962558df 100644
--- a/firmware/2lib/2rsa.c
+++ b/firmware/2lib/2rsa.c
@@ -342,7 +342,7 @@ vb2_error_t vb2_rsa_verify_digest(const struct vb2_public_key *key,
int sig_size;
int pad_size;
int exp;
- vb2_error_t rv;
+ vb2_error_t rv = VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
if (!key || !sig || !digest)
return VB2_ERROR_RSA_VERIFY_PARAM;
@@ -367,7 +367,22 @@ vb2_error_t vb2_rsa_verify_digest(const struct vb2_public_key *key,
return VB2_ERROR_RSA_VERIFY_WORKBUF;
}
- modpow(key, sig, workbuf32, exp);
+ if (key->allow_hwcrypto) {
+ rv = vb2ex_hwcrypto_modexp(key, sig, workbuf32, exp);
+
+ if (rv == VB2_SUCCESS)
+ VB2_DEBUG("Using HW modexp engine for sig_alg %d\n",
+ key->sig_alg);
+ else
+ VB2_DEBUG("HW modexp for sig_alg %d not supported, using SW\n",
+ key->sig_alg);
+ } else {
+ VB2_DEBUG("HW modexp forbidden, using SW\n");
+ }
+
+ if (rv != VB2_SUCCESS) {
+ modpow(key, sig, workbuf32, exp);
+ }
vb2_workbuf_free(&wblocal, 3 * key_bytes);
diff --git a/firmware/2lib/2stub_hwcrypto.c b/firmware/2lib/2stub_hwcrypto.c
index 542a5edc..56272ad4 100644
--- a/firmware/2lib/2stub_hwcrypto.c
+++ b/firmware/2lib/2stub_hwcrypto.c
@@ -34,3 +34,8 @@ vb2_error_t vb2ex_hwcrypto_rsa_verify_digest(const struct vb2_public_key *key,
return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
}
+__attribute__((weak))
+vb2_error_t vb2ex_hwcrypto_modexp(const struct vb2_public_key *key,
+ uint8_t *inout, uint32_t *workbuf32, int exp) {
+ return VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
+}
diff --git a/firmware/2lib/include/2api.h b/firmware/2lib/include/2api.h
index 6b95204b..67b5074a 100644
--- a/firmware/2lib/include/2api.h
+++ b/firmware/2lib/include/2api.h
@@ -966,6 +966,20 @@ vb2_error_t vb2ex_hwcrypto_rsa_verify_digest(const struct vb2_public_key *key,
const uint8_t *sig,
const uint8_t *digest);
+/**
+ * Calculate modexp using hardware crypto engine.
+ *
+ * @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
+ * @return VB2_SUCCESS or HWCRYPTO_UNSUPPORTED.
+ */
+vb2_error_t vb2ex_hwcrypto_modexp(const struct vb2_public_key *key,
+ uint8_t *inout,
+ uint32_t *workbuf32, int exp);
+
/*
* Abort vboot flow due to a failed assertion or broken assumption.
*
diff --git a/tests/vb20_rsa_padding_tests.c b/tests/vb20_rsa_padding_tests.c
index 8a0d58af..03a38ee1 100644
--- a/tests/vb20_rsa_padding_tests.c
+++ b/tests/vb20_rsa_padding_tests.c
@@ -14,6 +14,14 @@
#include "test_common.h"
#include "vb2_common.h"
+vb2_error_t hwcrypto_modexp_return_value = VB2_SUCCESS;
+vb2_error_t vb2ex_hwcrypto_modexp(const struct vb2_public_key *key,
+ uint8_t *inout,
+ uint32_t *workbuf32, int exp) {
+ return hwcrypto_modexp_return_value;
+}
+
+
/**
* Test valid and invalid signatures.
*/
@@ -67,6 +75,20 @@ static void test_verify_digest(struct vb2_public_key *key) {
TEST_EQ(vb2_rsa_verify_digest(key, NULL, test_message_sha1_hash, &wb),
VB2_ERROR_RSA_VERIFY_PARAM, "vb2_rsa_verify_digest() bad arg");
+ key->allow_hwcrypto = 1;
+ memcpy(sig, signatures[0], sizeof(sig));
+ vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
+ hwcrypto_modexp_return_value = VB2_SUCCESS;
+ TEST_NEQ(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),
+ VB2_SUCCESS, "vb2_rsa_verify_digest() hwcrypto modexp fails");
+
+ memcpy(sig, signatures[0], sizeof(sig));
+ vb2_workbuf_init(&wb, workbuf, sizeof(workbuf));
+ hwcrypto_modexp_return_value = VB2_ERROR_EX_HWCRYPTO_UNSUPPORTED;
+ TEST_SUCC(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),
+ "vb2_rsa_verify_digest() hwcrypto modexp fallback to sw");
+ key->allow_hwcrypto = 0;
+
memcpy(sig, signatures[0], sizeof(sig));
vb2_workbuf_init(&wb, workbuf, sizeof(sig) * 3 - 1);
TEST_EQ(vb2_rsa_verify_digest(key, sig, test_message_sha1_hash, &wb),