1 /*
2  * Copyright (c) 2020 Arm Limited
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include "adac_crypto_cc312.h"
7 
8 #include "psa_adac_config.h"
9 #include "psa_adac_debug.h"
10 #include <string.h>
11 
12 #include "pal/cc_pal_types.h"
13 #include "entropy_poll.h"
14 
hash_check(const uint8_t * a,size_t la,const uint8_t * b,size_t lb)15 static psa_status_t hash_check(const uint8_t *a, size_t la, const uint8_t *b,
16         size_t lb)
17 {
18     uint8_t chk = 1;
19 
20     if (la == lb) {
21         chk = 0;
22         for (size_t i = 0; i < la; i++) {
23             chk |= (uint8_t) (a[i] ^ b[i]);
24         }
25     }
26 
27     return chk == 0 ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE;
28 }
29 
30 /* API was put in place because there was no implementation of PSA
31  * Crypto API that supported PSA Crypto Drivers, but the goal is to
32  * migrate to it when it's ready. */
psa_adac_hash(psa_algorithm_t alg,const uint8_t * input,size_t input_size,uint8_t * hash,size_t hash_size,size_t * hash_length)33 psa_status_t psa_adac_hash(psa_algorithm_t alg, const uint8_t *input,
34         size_t input_size, uint8_t *hash, size_t hash_size,
35         size_t *hash_length)
36 {
37     return psa_adac_hash_multiple(alg, &input, &input_size, 1, hash, hash_size,
38                                         hash_length);
39 }
40 
psa_adac_hash_multiple(psa_algorithm_t alg,const uint8_t * inputs[],size_t input_sizes[],size_t input_count,uint8_t hash[],size_t hash_size,size_t * hash_length)41 psa_status_t psa_adac_hash_multiple(psa_algorithm_t alg,
42         const uint8_t *inputs[], size_t input_sizes[], size_t input_count,
43         uint8_t hash[], size_t hash_size, size_t *hash_length)
44 {
45     if (PSA_ALG_IS_VENDOR_DEFINED(alg)) {
46         /* TODO: Add support for extra algorithms */
47         return PSA_ERROR_NOT_SUPPORTED;
48     }
49 
50     psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
51     if (alg == PSA_ALG_SHA_256) {
52         if (hash_size < 32) {
53             return PSA_ERROR_INVALID_ARGUMENT;
54         }
55 
56         mbedtls_sha256_context ctx;
57         mbedtls_sha256_init(&ctx);
58 
59         status = mbedtls_sha256_starts(&ctx, 0) == 0 ?
60                         PSA_SUCCESS : PSA_ERROR_GENERIC_ERROR;
61 
62         for (size_t i = 0; (i < input_count) && (status == PSA_SUCCESS); i++) {
63             status = mbedtls_sha256_update(&ctx, inputs[i], input_sizes[i]) == 0 ?
64                      PSA_SUCCESS : PSA_ERROR_GENERIC_ERROR;
65         }
66         if (status == PSA_SUCCESS) {
67             status = mbedtls_sha256_finish(&ctx, hash) == 0 ?
68                                         PSA_SUCCESS : PSA_ERROR_GENERIC_ERROR;
69         }
70         if (status == PSA_SUCCESS) {
71             *hash_length = 32;
72         }
73         mbedtls_sha256_free(&ctx);
74     } else if (alg == PSA_ALG_SHA_512) {
75 #if defined (PSA_ADAC_EC_P521) || defined (PSA_ADAC_ED25519)
76         if (hash_size < 64) {
77             return PSA_ERROR_INVALID_ARGUMENT;
78         }
79 
80         mbedtls_sha512_context ctx;
81         mbedtls_sha512_init(&ctx);
82         status = mbedtls_sha512_starts_ret(&ctx, 0) == 0 ?
83                                 PSA_SUCCESS : PSA_ERROR_GENERIC_ERROR;
84         for (size_t i = 0; (i < input_count) && (status == PSA_SUCCESS); i++) {
85             status = mbedtls_sha512_update_ret(&ctx, inputs[i], input_sizes[i]) == 0 ?
86                      PSA_SUCCESS : PSA_ERROR_GENERIC_ERROR;
87         }
88         if (status == PSA_SUCCESS) {
89             status = mbedtls_sha512_finish_ret(&ctx, hash) == 0 ?
90                                 PSA_SUCCESS : PSA_ERROR_GENERIC_ERROR;
91         }
92         if (status == PSA_SUCCESS) {
93             *hash_length = 64;
94         }
95         mbedtls_sha512_free(&ctx);
96 #endif
97     }
98 
99     return status;
100 }
101 
psa_adac_hash_verify(psa_algorithm_t alg,const uint8_t input[],size_t input_length,uint8_t hash[],size_t hash_size)102 psa_status_t psa_adac_hash_verify(psa_algorithm_t alg, const uint8_t input[],
103         size_t input_length, uint8_t hash[], size_t hash_size)
104 {
105     size_t len = 0;
106     uint8_t computed_hash[64];
107     psa_status_t status = PSA_ERROR_GENERIC_ERROR;
108 
109     if (PSA_ALG_IS_VENDOR_DEFINED(alg)) {
110         // TODO: Add support for extra algorithms
111         return PSA_ERROR_NOT_SUPPORTED;
112     }
113 
114     status = psa_adac_hash_multiple(alg, &input, &input_length, 1,
115                                  computed_hash, sizeof(computed_hash), &len);
116     if (status == PSA_SUCCESS) {
117         if (hash_size != len) {
118             status = PSA_ERROR_INVALID_ARGUMENT;
119         } else {
120             status = hash_check(hash, len, computed_hash, len);
121         }
122     }
123 
124     return status;
125 }
126 
psa_adac_hash_verify_multiple(psa_algorithm_t alg,const uint8_t input[],size_t input_length,uint8_t * hash[],size_t hash_size[],size_t hash_count)127 psa_status_t psa_adac_hash_verify_multiple(psa_algorithm_t alg,
128         const uint8_t input[], size_t input_length, uint8_t *hash[],
129         size_t hash_size[], size_t hash_count)
130 {
131     size_t len = 0;
132     uint8_t computed_hash[64];
133     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
134 
135     if (PSA_ALG_IS_VENDOR_DEFINED(alg)) {
136         // TODO: Add support for extra algorithms
137         return PSA_ERROR_NOT_SUPPORTED;
138     }
139 
140     status = psa_adac_hash_multiple(alg, &input, &input_length, 1,
141             computed_hash, sizeof(computed_hash), &len);
142     if (status == PSA_SUCCESS) {
143         for (size_t i = 0; i < hash_count; i++) {
144             status = hash_check(hash[i], hash_size[i], computed_hash, len);
145             if (status == PSA_SUCCESS) {
146                 break;
147             }
148         }
149     }
150 
151     return status;
152 }
153