Embedded SDK
Embedded SDK
cx_hash.c
Go to the documentation of this file.
1 
2 /*******************************************************************************
3  * Ledger Nano S - Secure firmware
4  * (c) 2022 Ledger
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  ********************************************************************************/
18 
19 #include "app_config.h"
20 
21 #ifdef HAVE_HASH
22 
23 #include <string.h>
24 
25 #include "cx_hash.h"
26 #include "cx_utils.h"
27 #include "cx_ram.h"
28 
29 #include "cx_blake2b.h"
30 #include "cx_ripemd160.h"
31 #include "cx_sha256.h"
32 #include "cx_sha3.h"
33 #include "cx_sha512.h"
34 
35 #include "errors.h"
36 #include "exceptions.h"
37 
38 const cx_hash_info_t *cx_hash_get_info(cx_md_t md_type)
39 {
40  switch (md_type) {
41 #ifdef HAVE_SHA256
42  case CX_SHA256:
43  return &cx_sha256_info;
44 #endif
45 
46 #ifdef HAVE_RIPEMD160
47  case CX_RIPEMD160:
48  return &cx_ripemd160_info;
49 #endif
50 
51 #ifdef HAVE_SHA224
52  case CX_SHA224:
53  return &cx_sha224_info;
54 #endif
55 
56 #ifdef HAVE_SHA384
57  case CX_SHA384:
58  return &cx_sha384_info;
59 #endif
60 
61 #ifdef HAVE_SHA512
62  case CX_SHA512:
63  return &cx_sha512_info;
64 #endif
65 
66 #ifdef HAVE_SHA3
67  case CX_SHA3:
68  case CX_SHA3_256:
69  case CX_SHA3_512:
70  return &cx_sha3_info;
71  case CX_KECCAK:
72  return &cx_keccak_info;
73  case CX_SHAKE128:
74  return &cx_shake128_info;
75  case CX_SHAKE256:
76  return &cx_shake256_info;
77 #endif
78 
79 #ifdef HAVE_BLAKE2
80  case CX_BLAKE2B:
81  return &cx_blake2b_info;
82 #endif
83 
84  default:
85  return NULL;
86  }
87 }
88 
89 size_t cx_hash_get_size(const cx_hash_t *ctx)
90 {
91  const cx_hash_info_t *info = ctx->info;
92  if (info->output_size) {
93  return info->output_size;
94  }
95  return info->output_size_func(ctx);
96 }
97 
98 cx_err_t cx_hash_init(cx_hash_t *ctx, cx_md_t md_type)
99 {
100  const cx_hash_info_t *info = cx_hash_get_info(md_type);
101  if (info == NULL) {
102  return CX_INVALID_PARAMETER;
103  }
104  if (info->output_size == 0) { /* variable output size, must use cx_hash_init_ex */
105  return CX_INVALID_PARAMETER;
106  }
107  info->init_func(ctx);
108  return CX_OK;
109 }
110 
111 cx_err_t cx_hash_init_ex(cx_hash_t *ctx, cx_md_t md_type, size_t output_size)
112 {
113  const cx_hash_info_t *info = cx_hash_get_info(md_type);
114  if (info == NULL) {
115  return CX_INVALID_PARAMETER;
116  }
117  if (info->output_size != 0) {
118  if (info->output_size != output_size) {
119  return CX_INVALID_PARAMETER;
120  }
121  return cx_hash_init(ctx, md_type);
122  }
123  return info->init_ex_func(ctx, output_size * 8);
124 }
125 
126 cx_err_t cx_hash_update(cx_hash_t *ctx, const uint8_t *data, size_t len)
127 {
128  const cx_hash_info_t *info = ctx->info;
129  return info->update_func(ctx, data, len);
130 }
131 
132 cx_err_t cx_hash_final(cx_hash_t *ctx, uint8_t *digest)
133 {
134  const cx_hash_info_t *info = ctx->info;
135  return info->finish_func(ctx, digest);
136 }
137 
138 cx_err_t cx_hash_no_throw(cx_hash_t *hash,
139  uint32_t mode,
140  const uint8_t *in,
141  size_t len,
142  uint8_t *out,
143  size_t out_len)
144 {
145  unsigned int digest_len;
146  cx_err_t error;
147 
148  // --- init locals ---
149  digest_len = (unsigned int) cx_hash_get_size(hash);
150  CX_CHECK(cx_hash_update(hash, in, len));
151 
152  if (mode & CX_LAST) {
153  if (out_len < digest_len) {
154  return INVALID_PARAMETER;
155  }
156  CX_CHECK(cx_hash_final(hash, out));
157  }
158 
159 end:
160  return error;
161 }
162 
163 void cx_hash_destroy(cx_hash_t *hash_ctx)
164 {
165  explicit_bzero(hash_ctx, hash_ctx->info->ctx_size);
166 }
167 
168 #endif // HAVE_HASH
#define CX_LAST
Definition: lcx_common.h:115
unsigned char uint8_t
Definition: usbd_conf.h:53