1 /*
2 * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "esp_log.h"
7 #include "esp_secure_boot.h"
8 #include "mbedtls/sha256.h"
9 #include "mbedtls/x509.h"
10 #include "mbedtls/md.h"
11 #include "mbedtls/platform.h"
12 #include "mbedtls/entropy.h"
13 #include "mbedtls/ctr_drbg.h"
14
15 #include "secure_boot_signature_priv.h"
16
17 static const char *TAG = "secure_boot_v2_rsa";
18
verify_rsa_signature_block(const ets_secure_boot_signature_t * sig_block,const uint8_t * image_digest,const ets_secure_boot_sig_block_t * trusted_block)19 esp_err_t verify_rsa_signature_block(const ets_secure_boot_signature_t *sig_block, const uint8_t *image_digest, const ets_secure_boot_sig_block_t *trusted_block)
20 {
21 if (!sig_block || !image_digest || !trusted_block) {
22 return ESP_ERR_INVALID_ARG;
23 }
24
25 int ret = 0;
26 mbedtls_rsa_context pk;
27 mbedtls_entropy_context entropy;
28 mbedtls_ctr_drbg_context ctr_drbg;
29 const unsigned rsa_key_size = sizeof(sig_block->block[0].signature);
30 unsigned char *sig_be = calloc(1, rsa_key_size);
31 if (sig_be == NULL) {
32 return ESP_ERR_NO_MEM;
33 }
34 unsigned char *buf = calloc(1, rsa_key_size);
35 if (buf == NULL) {
36 free(sig_be);
37 return ESP_ERR_NO_MEM;
38 }
39
40 mbedtls_entropy_init(&entropy);
41 mbedtls_ctr_drbg_init(&ctr_drbg);
42 ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
43 if (ret != 0) {
44 ESP_LOGE(TAG, "mbedtls_ctr_drbg_seed returned -0x%04x\n", ret);
45 goto exit_outer;
46 }
47
48 const mbedtls_mpi N = { .MBEDTLS_PRIVATE(s) = 1,
49 .MBEDTLS_PRIVATE(n) = sizeof(trusted_block->key.n)/sizeof(mbedtls_mpi_uint),
50 .MBEDTLS_PRIVATE(p) = (void *)trusted_block->key.n,
51 };
52 const mbedtls_mpi e = { .MBEDTLS_PRIVATE(s) = 1,
53 .MBEDTLS_PRIVATE(n) = sizeof(trusted_block->key.e)/sizeof(mbedtls_mpi_uint), // 1
54 .MBEDTLS_PRIVATE(p) = (void *)&trusted_block->key.e,
55 };
56 mbedtls_rsa_init(&pk);
57 mbedtls_rsa_set_padding(&pk,MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
58 ret = mbedtls_rsa_import(&pk, &N, NULL, NULL, NULL, &e);
59 if (ret != 0) {
60 ESP_LOGE(TAG, "Failed mbedtls_rsa_import, err: %d", ret);
61 goto exit_inner;
62 }
63
64 ret = mbedtls_rsa_complete(&pk);
65 if (ret != 0) {
66 ESP_LOGE(TAG, "Failed mbedtls_rsa_complete, err: %d", ret);
67 goto exit_inner;
68 }
69
70 ret = mbedtls_rsa_check_pubkey(&pk);
71 if (ret != 0) {
72 ESP_LOGI(TAG, "Key is not an RSA key -%0x", -ret);
73 goto exit_inner;
74 }
75
76 /* Signature needs to be byte swapped into BE representation */
77 for (int j = 0; j < rsa_key_size; j++) {
78 sig_be[rsa_key_size - j - 1] = trusted_block->signature[j];
79 }
80
81 ret = mbedtls_rsa_public( &pk, sig_be, buf);
82 if (ret != 0) {
83 ESP_LOGE(TAG, "mbedtls_rsa_public failed, err: %d", ret);
84 goto exit_inner;
85 }
86
87 ret = mbedtls_rsa_rsassa_pss_verify( &pk, MBEDTLS_MD_SHA256, ESP_SECURE_BOOT_DIGEST_LEN, image_digest, sig_be);
88 if (ret != 0) {
89 ESP_LOGE(TAG, "Failed mbedtls_rsa_rsassa_pss_verify, err: %d", ret);
90 } else {
91 ESP_LOGI(TAG, "Signature verified successfully!");
92 }
93 exit_inner:
94 mbedtls_rsa_free(&pk);
95 exit_outer:
96 mbedtls_ctr_drbg_free(&ctr_drbg);
97 mbedtls_entropy_free(&entropy);
98 free(sig_be);
99 free(buf);
100 return ret;
101 }
102