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