1 /*
2 * Copyright 2021 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <errno.h>
9 #include <stdbool.h>
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include <arch_helpers.h>
16 #include "caam.h"
17 #include <common/debug.h>
18 #include <drivers/auth/crypto_mod.h>
19
20 #include "jobdesc.h"
21 #include "rsa.h"
22 #include "sec_hw_specific.h"
23
24 /* This array contains DER value for SHA-256 */
25 static const uint8_t hash_identifier[] = {
26 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
27 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
28 0x04, 0x20
29 };
30
rsa_done(uint32_t * desc,uint32_t status,void * arg,void * job_ring)31 static void rsa_done(uint32_t *desc, uint32_t status, void *arg,
32 void *job_ring)
33 {
34 INFO("RSA Desc SUCCESS with status %x\n", status);
35 }
36
rsa_public_verif_sec(uint8_t * sign,uint8_t * to,uint8_t * rsa_pub_key,uint32_t klen)37 static int rsa_public_verif_sec(uint8_t *sign, uint8_t *to,
38 uint8_t *rsa_pub_key, uint32_t klen)
39 {
40 int ret = 0;
41 struct rsa_context ctx __aligned(CACHE_WRITEBACK_GRANULE);
42 struct job_descriptor jobdesc __aligned(CACHE_WRITEBACK_GRANULE);
43
44 jobdesc.arg = NULL;
45 jobdesc.callback = rsa_done;
46
47 memset(&ctx, 0, sizeof(struct rsa_context));
48
49 ctx.pkin.a = sign;
50 ctx.pkin.a_siz = klen;
51 ctx.pkin.n = rsa_pub_key;
52 ctx.pkin.n_siz = klen;
53 ctx.pkin.e = rsa_pub_key + klen;
54 ctx.pkin.e_siz = klen;
55
56 cnstr_jobdesc_pkha_rsaexp(jobdesc.desc, &ctx.pkin, to, klen);
57
58 #if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2)
59 flush_dcache_range((uintptr_t)sign, klen);
60 flush_dcache_range((uintptr_t)rsa_pub_key, 2 * klen);
61 flush_dcache_range((uintptr_t)&ctx.pkin, sizeof(ctx.pkin));
62 inv_dcache_range((uintptr_t)to, klen);
63
64 dmbsy();
65 dsbsy();
66 isb();
67 #endif
68
69 /* Finally, generate the requested random data bytes */
70 ret = run_descriptor_jr(&jobdesc);
71 if (ret != 0) {
72 ERROR("Error in running descriptor\n");
73 ret = -1;
74 }
75 #if defined(SEC_MEM_NON_COHERENT) && defined(IMAGE_BL2)
76 inv_dcache_range((uintptr_t)to, klen);
77 dmbsy();
78 dsbsy();
79 isb();
80 #endif
81 return ret;
82 }
83
84 /*
85 * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
86 * pointers for padding, DER value and hash. And finally, constructs EM'
87 * which includes hash of complete CSF header and ESBC image. If SG flag
88 * is on, hash of SG table and entries is also included.
89 */
construct_img_encoded_hash_second(uint8_t * hash,uint8_t hash_len,uint8_t * encoded_hash_second,unsigned int key_len)90 static int construct_img_encoded_hash_second(uint8_t *hash, uint8_t hash_len,
91 uint8_t *encoded_hash_second,
92 unsigned int key_len)
93 {
94 /*
95 * RSA PKCSv1.5 encoding format for encoded message is below
96 * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
97 * PS is Padding String
98 * DER is DER value for SHA-256
99 * Hash is SHA-256 hash
100 * *********************************************************
101 * representative points to first byte of EM initially and is
102 * filled with 0x0
103 * representative is incremented by 1 and second byte is filled
104 * with 0x1
105 * padding points to third byte of EM
106 * digest points to full length of EM - 32 bytes
107 * hash_id (DER value) points to 19 bytes before pDigest
108 * separator is one byte which separates padding and DER
109 */
110
111 unsigned int len;
112 uint8_t *representative;
113 uint8_t *padding, *digest;
114 uint8_t *hash_id, *separator;
115 int i;
116 int ret = 0;
117
118 if (hash_len != SHA256_BYTES) {
119 return -1;
120 }
121
122 /* Key length = Modulus length */
123 len = (key_len / 2U) - 1U;
124 representative = encoded_hash_second;
125 representative[0] = 0U;
126 representative[1] = 1U; /* block type 1 */
127
128 padding = &representative[2];
129 digest = &representative[1] + len - 32;
130 hash_id = digest - sizeof(hash_identifier);
131 separator = hash_id - 1;
132
133 /* fill padding area pointed by padding with 0xff */
134 memset(padding, 0xff, separator - padding);
135
136 /* fill byte pointed by separator */
137 *separator = 0U;
138
139 /* fill SHA-256 DER value pointed by HashId */
140 memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
141
142 /* fill hash pointed by Digest */
143 for (i = 0; i < SHA256_BYTES; i++) {
144 digest[i] = hash[i];
145 }
146
147 return ret;
148 }
149
rsa_verify_signature(void * hash_ptr,unsigned int hash_len,void * sig_ptr,unsigned int sig_len,void * pk_ptr,unsigned int pk_len)150 int rsa_verify_signature(void *hash_ptr, unsigned int hash_len,
151 void *sig_ptr, unsigned int sig_len,
152 void *pk_ptr, unsigned int pk_len)
153 {
154 uint8_t img_encoded_hash_second[RSA_4K_KEY_SZ_BYTES];
155 uint8_t encoded_hash[RSA_4K_KEY_SZ_BYTES] __aligned(CACHE_WRITEBACK_GRANULE);
156 int ret = 0;
157
158 ret = construct_img_encoded_hash_second(hash_ptr, hash_len,
159 img_encoded_hash_second,
160 pk_len);
161 if (ret != 0) {
162 ERROR("Encoded Hash Failure\n");
163 return CRYPTO_ERR_SIGNATURE;
164 }
165
166 ret = rsa_public_verif_sec(sig_ptr, encoded_hash, pk_ptr, pk_len / 2);
167 if (ret != 0) {
168 ERROR("RSA signature Failure\n");
169 return CRYPTO_ERR_SIGNATURE;
170 }
171
172 ret = memcmp(img_encoded_hash_second, encoded_hash, sig_len);
173 if (ret != 0) {
174 ERROR("Comparison Failure\n");
175 return CRYPTO_ERR_SIGNATURE;
176 }
177
178 return CRYPTO_SUCCESS;
179 }
180