1 /*
2  * Copyright 2021 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include <stddef.h>
9 #include <string.h>
10 
11 #include "caam.h"
12 #include <common/debug.h>
13 #include <drivers/auth/crypto_mod.h>
14 
15 #include "hash.h"
16 #include "rsa.h"
17 
18 #define LIB_NAME		"NXP crypto"
19 
20 /*
21  * Initialize the library and export the descriptor
22  */
init(void)23 static void init(void)
24 {
25 	/* Initialize NXP crypto library`:*/
26 	NOTICE("Initializing & configuring SEC block.\n");
27 
28 	if (config_sec_block() < 0) {
29 		ERROR("Init & config failure for caam.\n");
30 	}
31 }
32 
33 /*
34  * Verify a signature.
35  *
36  * For IMG_PLAT - data points to a PKCS#1.5 encoded HASH
37  * sig_alg will be RSA or ECC
38  * Parameters are passed using the DER encoding format following the ASN.1
39  * structures detailed above.
40  */
verify_signature(void * data_ptr,unsigned int data_len,void * sig_ptr,unsigned int sig_len,void * sign_alg,unsigned int sig_alg_len,void * pk_ptr,unsigned int pk_len)41 static int verify_signature(void *data_ptr, unsigned int data_len,
42 			    void *sig_ptr, unsigned int sig_len,
43 			    void *sign_alg, unsigned int sig_alg_len,
44 			    void *pk_ptr, unsigned int pk_len)
45 {
46 	int ret = CRYPTO_SUCCESS;
47 
48 	enum sig_alg alg = *(enum sig_alg *)sign_alg;
49 
50 	switch (alg) {
51 	case RSA:
52 		NOTICE("Verifying RSA\n");
53 		ret = rsa_verify_signature(data_ptr, data_len, sig_ptr, sig_len,
54 					   pk_ptr, pk_len);
55 		break;
56 	case ECC:
57 	default:
58 		ret = CRYPTO_ERR_SIGNATURE;
59 		break;
60 	}
61 
62 	if (ret != 0) {
63 		ERROR("RSA verification Failed\n");
64 	}
65 	return ret;
66 
67 }
68 
69 /*
70  * Match a hash
71  *
72  * Digest info is passed as a table of SHA-26 hashes and digest_info_len
73  * is number of entries in the table
74  * This implementation is very specific to the CSF header parser ROTPK
75  * comparison.
76  */
verify_hash(void * data_ptr,unsigned int data_len,void * digest_info_ptr,unsigned int digest_info_len)77 static int verify_hash(void *data_ptr, unsigned int data_len,
78 		       void *digest_info_ptr, unsigned int digest_info_len)
79 {
80 	void *ctx = NULL;
81 	int i = 0, ret = 0;
82 	enum hash_algo algo = SHA256;
83 	uint8_t hash[SHA256_BYTES] __aligned(CACHE_WRITEBACK_GRANULE) = {0};
84 	uint32_t digest_size = SHA256_BYTES;
85 	uint8_t *hash_tbl = digest_info_ptr;
86 
87 	NOTICE("Verifying hash\n");
88 	ret = hash_init(algo, &ctx);
89 	if (ret != 0) {
90 		return CRYPTO_ERR_HASH;
91 	}
92 
93 	/* Update hash with that of SRK table */
94 	ret = hash_update(algo, ctx, data_ptr, data_len);
95 	if (ret != 0) {
96 		return CRYPTO_ERR_HASH;
97 	}
98 
99 	/* Copy hash at destination buffer */
100 	ret = hash_final(algo, ctx, hash, digest_size);
101 	if (ret != 0) {
102 		return CRYPTO_ERR_HASH;
103 	}
104 
105 	VERBOSE("%s Calculated hash\n", __func__);
106 	for (i = 0; i < SHA256_BYTES/4; i++) {
107 		VERBOSE("%x\n", *((uint32_t *)hash + i));
108 	}
109 
110 	for (i = 0; i < digest_info_len; i++) {
111 		if (memcmp(hash, (hash_tbl + (i * digest_size)),
112 			   digest_size) == 0) {
113 			return CRYPTO_SUCCESS;
114 		}
115 	}
116 
117 	return CRYPTO_ERR_HASH;
118 }
119 
120 /*
121  * Register crypto library descriptor
122  */
123 REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
124