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