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