diff options
-rw-r--r-- | firmware/2lib/2rsa.c | 19 | ||||
-rw-r--r-- | firmware/2lib/2stub_hwcrypto.c | 5 | ||||
-rw-r--r-- | firmware/2lib/include/2api.h | 14 | ||||
-rw-r--r-- | tests/vb20_rsa_padding_tests.c | 22 |
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), |