NCBI C++ ToolKit
psa_crypto_aead.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  * PSA AEAD entry points
3  */
4 /*
5  * Copyright The Mbed TLS Contributors
6  * SPDX-License-Identifier: Apache-2.0
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License"); you may
9  * not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #include "common.h"
22 
23 #if defined(MBEDTLS_PSA_CRYPTO_C)
24 
25 #include "psa_crypto_aead.h"
26 #include "psa_crypto_core.h"
27 #include "psa_crypto_cipher.h"
28 
29 #include "mbedtls/ccm.h"
30 #include "mbedtls/chachapoly.h"
31 #include "mbedtls/cipher.h"
32 #include "mbedtls/gcm.h"
33 
34 typedef struct {
37  union {
38  unsigned dummy; /* Make the union non-empty even with no supported algorithms. */
39 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
41 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
42 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
44 #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
45 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
46  mbedtls_chachapoly_context chachapoly;
47 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
48  } ctx;
50 
51 #define AEAD_OPERATION_INIT { 0, 0, { 0 } }
52 
54 {
55  switch (operation->core_alg) {
56 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
57  case PSA_ALG_CCM:
58  mbedtls_ccm_free(&operation->ctx.ccm);
59  break;
60 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
61 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
62  case PSA_ALG_GCM:
63  mbedtls_gcm_free(&operation->ctx.gcm);
64  break;
65 #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
66 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
68  mbedtls_chachapoly_free(&operation->ctx.chachapoly);
69  break;
70 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
71  }
72 }
73 
77  const uint8_t *key_buffer,
78  psa_algorithm_t alg)
79 {
81  size_t key_bits;
82  const mbedtls_cipher_info_t *cipher_info;
83  mbedtls_cipher_id_t cipher_id;
84  size_t full_tag_length = 0;
85 
86  key_bits = attributes->core.bits;
87 
88  cipher_info = mbedtls_cipher_info_from_psa(alg,
89  attributes->core.type, key_bits,
90  &cipher_id);
91  if (cipher_info == NULL) {
93  }
94 
95  switch (PSA_ALG_AEAD_WITH_SHORTENED_TAG(alg, 0)) {
96 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
98  operation->core_alg = PSA_ALG_CCM;
99  full_tag_length = 16;
100  /* CCM allows the following tag lengths: 4, 6, 8, 10, 12, 14, 16.
101  * The call to mbedtls_ccm_encrypt_and_tag or
102  * mbedtls_ccm_auth_decrypt will validate the tag length. */
103  if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
105  }
106 
107  mbedtls_ccm_init(&operation->ctx.ccm);
108  status = mbedtls_to_psa_error(
109  mbedtls_ccm_setkey(&operation->ctx.ccm, cipher_id,
110  key_buffer, (unsigned int) key_bits));
111  if (status != PSA_SUCCESS) {
112  return status;
113  }
114  break;
115 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
116 
117 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
119  operation->core_alg = PSA_ALG_GCM;
120  full_tag_length = 16;
121  /* GCM allows the following tag lengths: 4, 8, 12, 13, 14, 15, 16.
122  * The call to mbedtls_gcm_crypt_and_tag or
123  * mbedtls_gcm_auth_decrypt will validate the tag length. */
124  if (PSA_BLOCK_CIPHER_BLOCK_LENGTH(attributes->core.type) != 16) {
126  }
127 
128  mbedtls_gcm_init(&operation->ctx.gcm);
129  status = mbedtls_to_psa_error(
130  mbedtls_gcm_setkey(&operation->ctx.gcm, cipher_id,
131  key_buffer, (unsigned int) key_bits));
132  if (status != PSA_SUCCESS) {
133  return status;
134  }
135  break;
136 #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
137 
138 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
141  full_tag_length = 16;
142  /* We only support the default tag length. */
143  if (alg != PSA_ALG_CHACHA20_POLY1305) {
145  }
146 
147  mbedtls_chachapoly_init(&operation->ctx.chachapoly);
148  status = mbedtls_to_psa_error(
149  mbedtls_chachapoly_setkey(&operation->ctx.chachapoly,
150  key_buffer));
151  if (status != PSA_SUCCESS) {
152  return status;
153  }
154  break;
155 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
156 
157  default:
158  (void) status;
159  (void) key_buffer;
161  }
162 
164  key_bits, alg)
165  > full_tag_length) {
167  }
168 
169  operation->tag_length = PSA_AEAD_TAG_LENGTH(attributes->core.type,
170  key_bits,
171  alg);
172 
173  return PSA_SUCCESS;
174 }
175 
178  const uint8_t *key_buffer, size_t key_buffer_size,
179  psa_algorithm_t alg,
180  const uint8_t *nonce, size_t nonce_length,
181  const uint8_t *additional_data, size_t additional_data_length,
182  const uint8_t *plaintext, size_t plaintext_length,
183  uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length)
184 {
187  uint8_t *tag;
188  (void) key_buffer_size;
189 
190  status = psa_aead_setup(&operation, attributes, key_buffer, alg);
191  if (status != PSA_SUCCESS) {
192  goto exit;
193  }
194 
195  /* For all currently supported modes, the tag is at the end of the
196  * ciphertext. */
197  if (ciphertext_size < (plaintext_length + operation.tag_length)) {
199  goto exit;
200  }
201  tag = ciphertext + plaintext_length;
202 
203 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
204  if (operation.core_alg == PSA_ALG_CCM) {
205  status = mbedtls_to_psa_error(
207  plaintext_length,
208  nonce, nonce_length,
209  additional_data,
210  additional_data_length,
211  plaintext, ciphertext,
212  tag, operation.tag_length));
213  } else
214 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
215 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
216  if (operation.core_alg == PSA_ALG_GCM) {
217  status = mbedtls_to_psa_error(
220  plaintext_length,
221  nonce, nonce_length,
222  additional_data, additional_data_length,
223  plaintext, ciphertext,
224  operation.tag_length, tag));
225  } else
226 #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
227 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
228  if (operation.core_alg == PSA_ALG_CHACHA20_POLY1305) {
229  if (nonce_length != 12) {
230  if (nonce_length == 8) {
231  status = PSA_ERROR_NOT_SUPPORTED;
232  } else {
234  }
235  goto exit;
236  }
237 
238  if (operation.tag_length != 16) {
239  status = PSA_ERROR_NOT_SUPPORTED;
240  goto exit;
241  }
242  status = mbedtls_to_psa_error(
244  plaintext_length,
245  nonce,
246  additional_data,
247  additional_data_length,
248  plaintext,
249  ciphertext,
250  tag));
251  } else
252 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
253  {
254  (void) tag;
255  (void) nonce;
256  (void) nonce_length;
257  (void) additional_data;
258  (void) additional_data_length;
259  (void) plaintext;
261  }
262 
263  if (status == PSA_SUCCESS) {
264  *ciphertext_length = plaintext_length + operation.tag_length;
265  }
266 
267 exit:
269 
270  return status;
271 }
272 
273 /* Locate the tag in a ciphertext buffer containing the encrypted data
274  * followed by the tag. Return the length of the part preceding the tag in
275  * *plaintext_length. This is the size of the plaintext in modes where
276  * the encrypted data has the same size as the plaintext, such as
277  * CCM and GCM. */
279  const uint8_t *ciphertext,
280  size_t ciphertext_length,
281  size_t plaintext_size,
282  const uint8_t **p_tag)
283 {
284  size_t payload_length;
285  if (tag_length > ciphertext_length) {
287  }
288  payload_length = ciphertext_length - tag_length;
289  if (payload_length > plaintext_size) {
291  }
292  *p_tag = ciphertext + payload_length;
293  return PSA_SUCCESS;
294 }
295 
298  const uint8_t *key_buffer, size_t key_buffer_size,
299  psa_algorithm_t alg,
300  const uint8_t *nonce, size_t nonce_length,
301  const uint8_t *additional_data, size_t additional_data_length,
302  const uint8_t *ciphertext, size_t ciphertext_length,
303  uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length)
304 {
307  const uint8_t *tag = NULL;
308  (void) key_buffer_size;
309 
310  status = psa_aead_setup(&operation, attributes, key_buffer, alg);
311  if (status != PSA_SUCCESS) {
312  goto exit;
313  }
314 
315  status = psa_aead_unpadded_locate_tag(operation.tag_length,
316  ciphertext, ciphertext_length,
317  plaintext_size, &tag);
318  if (status != PSA_SUCCESS) {
319  goto exit;
320  }
321 
322 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CCM)
323  if (operation.core_alg == PSA_ALG_CCM) {
324  status = mbedtls_to_psa_error(
326  ciphertext_length - operation.tag_length,
327  nonce, nonce_length,
328  additional_data,
329  additional_data_length,
330  ciphertext, plaintext,
331  tag, operation.tag_length));
332  } else
333 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CCM */
334 #if defined(MBEDTLS_PSA_BUILTIN_ALG_GCM)
335  if (operation.core_alg == PSA_ALG_GCM) {
336  status = mbedtls_to_psa_error(
338  ciphertext_length - operation.tag_length,
339  nonce, nonce_length,
340  additional_data,
341  additional_data_length,
342  tag, operation.tag_length,
343  ciphertext, plaintext));
344  } else
345 #endif /* MBEDTLS_PSA_BUILTIN_ALG_GCM */
346 #if defined(MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305)
347  if (operation.core_alg == PSA_ALG_CHACHA20_POLY1305) {
348  if (nonce_length != 12) {
349  if (nonce_length == 8) {
350  status = PSA_ERROR_NOT_SUPPORTED;
351  } else {
353  }
354  goto exit;
355  }
356 
357  if (operation.tag_length != 16) {
358  status = PSA_ERROR_NOT_SUPPORTED;
359  goto exit;
360  }
361  status = mbedtls_to_psa_error(
363  ciphertext_length - operation.tag_length,
364  nonce,
365  additional_data,
366  additional_data_length,
367  tag,
368  ciphertext,
369  plaintext));
370  } else
371 #endif /* MBEDTLS_PSA_BUILTIN_ALG_CHACHA20_POLY1305 */
372  {
373  (void) nonce;
374  (void) nonce_length;
375  (void) additional_data;
376  (void) additional_data_length;
377  (void) plaintext;
379  }
380 
381  if (status == PSA_SUCCESS) {
382  *plaintext_length = ciphertext_length - operation.tag_length;
383  }
384 
385 exit:
387 
388  if (status == PSA_SUCCESS) {
389  *plaintext_length = ciphertext_length - operation.tag_length;
390  }
391  return status;
392 }
393 
394 #endif /* MBEDTLS_PSA_CRYPTO_C */
static const struct attribute attributes[]
Definition: attributes.c:165
This file provides an API for the CCM authenticated encryption mode for block ciphers.
void mbedtls_ccm_free(mbedtls_ccm_context *ctx)
This function releases and clears the specified CCM context and underlying cipher sub-context.
int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx, mbedtls_cipher_id_t cipher, const unsigned char *key, unsigned int keybits)
This function initializes the CCM context set in the ctx parameter and sets the encryption key.
int mbedtls_ccm_encrypt_and_tag(mbedtls_ccm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, unsigned char *tag, size_t tag_len)
This function encrypts a buffer using CCM.
int mbedtls_ccm_auth_decrypt(mbedtls_ccm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, const unsigned char *tag, size_t tag_len)
This function performs a CCM authenticated decryption of a buffer.
void mbedtls_ccm_init(mbedtls_ccm_context *ctx)
This function initializes the specified CCM context, to make references valid, and prepare the contex...
This file contains the AEAD-ChaCha20-Poly1305 definitions and functions.
void mbedtls_chachapoly_init(mbedtls_chachapoly_context *ctx)
This function initializes the specified ChaCha20-Poly1305 context.
int mbedtls_chachapoly_setkey(mbedtls_chachapoly_context *ctx, const unsigned char key[32])
This function sets the ChaCha20-Poly1305 symmetric encryption key.
void mbedtls_chachapoly_free(mbedtls_chachapoly_context *ctx)
This function releases and clears the specified ChaCha20-Poly1305 context.
int mbedtls_chachapoly_encrypt_and_tag(mbedtls_chachapoly_context *ctx, size_t length, const unsigned char nonce[12], const unsigned char *aad, size_t aad_len, const unsigned char *input, unsigned char *output, unsigned char tag[16])
This function performs a complete ChaCha20-Poly1305 authenticated encryption with the previously-set ...
int mbedtls_chachapoly_auth_decrypt(mbedtls_chachapoly_context *ctx, size_t length, const unsigned char nonce[12], const unsigned char *aad, size_t aad_len, const unsigned char tag[16], const unsigned char *input, unsigned char *output)
This function performs a complete ChaCha20-Poly1305 authenticated decryption with the previously-set ...
This file contains an abstraction interface for use with the cipher primitives provided by the librar...
mbedtls_cipher_id_t
Supported cipher types.
Definition: cipher.h:90
#define PSA_AEAD_TAG_LENGTH(key_type, key_bits, alg)
The length of a tag for an AEAD algorithm, in bytes.
Definition: crypto_sizes.h:175
CS_CONTEXT * ctx
Definition: t0006.c:12
This file contains GCM definitions and functions.
#define MBEDTLS_GCM_ENCRYPT
Definition: gcm.h:44
int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx, int mode, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *input, unsigned char *output, size_t tag_len, unsigned char *tag)
This function performs GCM encryption or decryption of a buffer.
void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
This function initializes the specified GCM context, to make references valid, and prepares the conte...
int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx, mbedtls_cipher_id_t cipher, const unsigned char *key, unsigned int keybits)
This function associates a GCM context with a cipher algorithm and a key.
void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
This function clears a GCM context and the underlying cipher sub-context.
int mbedtls_gcm_auth_decrypt(mbedtls_gcm_context *ctx, size_t length, const unsigned char *iv, size_t iv_len, const unsigned char *add, size_t add_len, const unsigned char *tag, size_t tag_len, const unsigned char *input, unsigned char *output)
This function performs a GCM authenticated decryption of a buffer.
#define NULL
Definition: ncbistd.hpp:225
operation
Bit operations.
Definition: bmconst.h:191
#define PSA_ALG_GCM
The GCM authenticated encryption algorithm.
#define PSA_ALG_CHACHA20_POLY1305
The Chacha20-Poly1305 AEAD algorithm.
#define PSA_ALG_AEAD_WITH_SHORTENED_TAG(aead_alg, tag_length)
Macro to build a shortened AEAD algorithm.
#define PSA_ALG_CCM
The CCM authenticated encryption algorithm.
uint32_t psa_algorithm_t
Encoding of a cryptographic algorithm.
Definition: crypto_types.h:137
#define PSA_BLOCK_CIPHER_BLOCK_LENGTH(type)
The block size of a block cipher.
int32_t psa_status_t
Function return status.
Definition: crypto_types.h:62
#define PSA_ERROR_CORRUPTION_DETECTED
A tampering attempt was detected.
#define PSA_ERROR_NOT_SUPPORTED
The requested operation or a parameter is not supported by this implementation.
Definition: crypto_values.h:84
#define PSA_SUCCESS
The action was completed successfully.
Definition: crypto_values.h:68
#define PSA_ERROR_BUFFER_TOO_SMALL
An output buffer is too small.
#define PSA_ERROR_INVALID_ARGUMENT
The parameters passed to the function are invalid.
exit(2)
const char * tag
#define mbedtls_to_psa_error
#define AEAD_OPERATION_INIT
static psa_status_t psa_aead_unpadded_locate_tag(size_t tag_length, const uint8_t *ciphertext, size_t ciphertext_length, size_t plaintext_size, const uint8_t **p_tag)
static void psa_aead_abort_internal(aead_operation_t *operation)
static psa_status_t psa_aead_setup(aead_operation_t *operation, const psa_key_attributes_t *attributes, const uint8_t *key_buffer, psa_algorithm_t alg)
psa_status_t mbedtls_psa_aead_encrypt(const psa_key_attributes_t *attributes, const uint8_t *key_buffer, size_t key_buffer_size, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, const uint8_t *additional_data, size_t additional_data_length, const uint8_t *plaintext, size_t plaintext_length, uint8_t *ciphertext, size_t ciphertext_size, size_t *ciphertext_length)
Process an authenticated encryption operation.
psa_status_t mbedtls_psa_aead_decrypt(const psa_key_attributes_t *attributes, const uint8_t *key_buffer, size_t key_buffer_size, psa_algorithm_t alg, const uint8_t *nonce, size_t nonce_length, const uint8_t *additional_data, size_t additional_data_length, const uint8_t *ciphertext, size_t ciphertext_length, uint8_t *plaintext, size_t plaintext_size, size_t *plaintext_length)
Process an authenticated decryption operation.
const mbedtls_cipher_info_t * mbedtls_cipher_info_from_psa(psa_algorithm_t alg, psa_key_type_t key_type, size_t key_bits, mbedtls_cipher_id_t *cipher_id)
Get Mbed TLS cipher information given the cipher algorithm PSA identifier as well as the PSA type and...
unsigned char uint8_t
Definition: stdint.h:124
psa_algorithm_t core_alg
test_type_t type
Definition: attributes.c:161
The CCM context-type definition.
Definition: ccm.h:79
Cipher information.
Definition: cipher.h:276
The GCM context structure.
Definition: gcm.h:66
Modified on Thu Nov 30 04:54:12 2023 by modify_doxy.py rev. 669887