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