Embedded SDK
Embedded SDK
cx_aead.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 #if defined(HAVE_AEAD)
20 #include "lcx_aead.h"
21 #include "lcx_common.h"
22 #include "cx_utils.h"
23 #include <string.h>
24 
25 #if defined(HAVE_AES_GCM)
26 #include "cx_aes_gcm.h"
27 #endif // HAVE_AES
28 #if defined(HAVE_CHACHA_POLY) && defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
29 #include "cx_chacha_poly.h"
30 #endif
31 
32 const cx_aead_info_t *cx_aead_get_info(cx_aead_type_t type)
33 {
34  switch (type) {
35 #if defined(HAVE_AES_GCM)
36  case CX_AEAD_AES128_GCM:
37  return &cx_aes128_gcm_info;
38  case CX_AEAD_AES192_GCM:
39  return &cx_aes192_gcm_info;
40  case CX_AEAD_AES256_GCM:
41  return &cx_aes256_gcm_info;
42 #endif // HAVE_AES_GCM
43 #if defined(HAVE_CHACHA_POLY) && defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
44  case CX_AEAD_CHACHA20_POLY1305:
45  return &cx_chacha20_poly1305_info;
46 #endif
47  default:
48  return NULL;
49  }
50 }
51 
52 cx_err_t cx_aead_init(cx_aead_context_t *ctx)
53 {
54  if (NULL == ctx) {
55  return CX_INVALID_PARAMETER;
56  }
57  memset(ctx, 0, sizeof(cx_aead_context_t));
58  return CX_OK;
59 }
60 
61 cx_err_t cx_aead_setup(cx_aead_context_t *ctx, cx_aead_type_t type)
62 {
63  const cx_aead_info_t *info = cx_aead_get_info(type);
64  if (NULL == info) {
65  return CX_INVALID_PARAMETER;
66  }
67  ctx->info = info;
68  ctx->info->func->init(ctx->base_ctx);
69  return CX_OK;
70 }
71 
72 cx_err_t cx_aead_set_key(cx_aead_context_t *ctx, const uint8_t *key, size_t key_len, uint32_t mode)
73 {
74  if (ctx->info->key_bitlen != key_len * 8) {
75  return CX_INVALID_PARAMETER_SIZE;
76  }
77  if ((mode != CX_ENCRYPT) && (mode != CX_DECRYPT)) {
78  return CX_INVALID_PARAMETER_VALUE;
79  }
80  ctx->mode = mode;
81  return ctx->info->func->set_key(ctx->base_ctx, key, key_len);
82 }
83 
84 cx_err_t cx_aead_set_iv(cx_aead_context_t *ctx, const uint8_t *iv, size_t iv_len)
85 {
86  if ((NULL == iv) || (iv_len < 1)) {
87  return CX_INVALID_PARAMETER;
88  }
89  if (NULL == ctx->info) {
90  return CX_INVALID_PARAMETER;
91  }
92  return ctx->info->func->start(ctx->base_ctx, ctx->mode, iv, iv_len);
93 }
94 
95 cx_err_t cx_aead_update_ad(cx_aead_context_t *ctx, const uint8_t *ad, size_t ad_len)
96 {
97  if (NULL == ctx->info) {
98  return CX_INVALID_PARAMETER;
99  }
100  return ctx->info->func->update_aad(ctx->base_ctx, ad, ad_len);
101 }
102 
103 cx_err_t cx_aead_update(cx_aead_context_t *ctx,
104  uint8_t *in,
105  size_t in_len,
106  uint8_t *out,
107  size_t *out_len)
108 {
109  if ((NULL == ctx->info) || (NULL == out_len)) {
110  return CX_INVALID_PARAMETER;
111  }
112  *out_len = in_len;
113  return ctx->info->func->update(ctx->base_ctx, in, out, in_len);
114 }
115 
116 cx_err_t cx_aead_write_tag(cx_aead_context_t *ctx, uint8_t *tag, size_t tag_len)
117 {
118  if ((NULL == ctx->info) || (NULL == tag)) {
119  return CX_INVALID_PARAMETER;
120  }
121  return ctx->info->func->finish(ctx->base_ctx, tag, tag_len);
122 }
123 
124 cx_err_t cx_aead_check_tag(cx_aead_context_t *ctx, const uint8_t *tag, size_t tag_len)
125 {
126  if ((NULL == ctx->info) || (ctx->mode != CX_DECRYPT)) {
127  return CX_INVALID_PARAMETER;
128  }
129 
130  return ctx->info->func->check_tag(ctx->base_ctx, tag, tag_len);
131 }
132 
133 cx_err_t cx_aead_encrypt(cx_aead_context_t *ctx,
134  const uint8_t *iv,
135  size_t iv_len,
136  const uint8_t *ad,
137  size_t ad_len,
138  uint8_t *in,
139  size_t in_len,
140  uint8_t *out,
141  size_t *out_len,
142  uint8_t *tag,
143  size_t tag_len)
144 {
145  if (NULL == ctx->info) {
146  return CX_INVALID_PARAMETER;
147  }
148  *out_len = in_len;
149  return ctx->info->func->encrypt_and_tag(
150  ctx->base_ctx, in, in_len, iv, iv_len, ad, ad_len, out, tag, tag_len);
151 }
152 
153 cx_err_t cx_aead_decrypt(cx_aead_context_t *ctx,
154  const uint8_t *iv,
155  size_t iv_len,
156  const uint8_t *ad,
157  size_t ad_len,
158  uint8_t *in,
159  size_t in_len,
160  uint8_t *out,
161  size_t *out_len,
162  const uint8_t *tag,
163  size_t tag_len)
164 {
165  if (NULL == ctx->info) {
166  return CX_INVALID_PARAMETER;
167  }
168  *out_len = in_len;
169  return ctx->info->func->auth_decrypt(
170  ctx->base_ctx, in, in_len, iv, iv_len, ad, ad_len, out, tag, tag_len);
171 }
172 
173 #endif // HAVE_AEAD
Authenticated Encryption with Associated Data (AEAD)
Cryptography flags.
#define CX_ENCRYPT
Definition: lcx_common.h:126
#define CX_DECRYPT
Definition: lcx_common.h:127
unsigned char uint8_t
Definition: usbd_conf.h:53