1 /**
2  * \file block_cipher.c
3  *
4  * \brief Lightweight abstraction layer for block ciphers with 128 bit blocks,
5  * for use by the GCM and CCM modules.
6  */
7 /*
8  *  Copyright The Mbed TLS Contributors
9  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
10  */
11 
12 #include "common.h"
13 
14 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
15 #include "psa/crypto.h"
16 #include "psa_crypto_core.h"
17 #include "psa_util_internal.h"
18 #endif
19 
20 #include "block_cipher_internal.h"
21 
22 #if defined(MBEDTLS_BLOCK_CIPHER_C)
23 
24 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id)25 static psa_key_type_t psa_key_type_from_block_cipher_id(mbedtls_block_cipher_id_t cipher_id)
26 {
27     switch (cipher_id) {
28 #if defined(MBEDTLS_BLOCK_CIPHER_AES_VIA_PSA)
29         case MBEDTLS_BLOCK_CIPHER_ID_AES:
30             return PSA_KEY_TYPE_AES;
31 #endif
32 #if defined(MBEDTLS_BLOCK_CIPHER_ARIA_VIA_PSA)
33         case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
34             return PSA_KEY_TYPE_ARIA;
35 #endif
36 #if defined(MBEDTLS_BLOCK_CIPHER_CAMELLIA_VIA_PSA)
37         case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
38             return PSA_KEY_TYPE_CAMELLIA;
39 #endif
40         default:
41             return PSA_KEY_TYPE_NONE;
42     }
43 }
44 
mbedtls_cipher_error_from_psa(psa_status_t status)45 static int mbedtls_cipher_error_from_psa(psa_status_t status)
46 {
47     return PSA_TO_MBEDTLS_ERR_LIST(status, psa_to_cipher_errors,
48                                    psa_generic_status_to_mbedtls);
49 }
50 #endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
51 
mbedtls_block_cipher_free(mbedtls_block_cipher_context_t * ctx)52 void mbedtls_block_cipher_free(mbedtls_block_cipher_context_t *ctx)
53 {
54     if (ctx == NULL) {
55         return;
56     }
57 
58 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
59     if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
60         psa_destroy_key(ctx->psa_key_id);
61         return;
62     }
63 #endif
64     switch (ctx->id) {
65 #if defined(MBEDTLS_AES_C)
66         case MBEDTLS_BLOCK_CIPHER_ID_AES:
67             mbedtls_aes_free(&ctx->ctx.aes);
68             break;
69 #endif
70 #if defined(MBEDTLS_ARIA_C)
71         case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
72             mbedtls_aria_free(&ctx->ctx.aria);
73             break;
74 #endif
75 #if defined(MBEDTLS_CAMELLIA_C)
76         case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
77             mbedtls_camellia_free(&ctx->ctx.camellia);
78             break;
79 #endif
80         default:
81             break;
82     }
83     ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
84 }
85 
mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t * ctx,mbedtls_cipher_id_t cipher_id)86 int mbedtls_block_cipher_setup(mbedtls_block_cipher_context_t *ctx,
87                                mbedtls_cipher_id_t cipher_id)
88 {
89     ctx->id = (cipher_id == MBEDTLS_CIPHER_ID_AES) ? MBEDTLS_BLOCK_CIPHER_ID_AES :
90               (cipher_id == MBEDTLS_CIPHER_ID_ARIA) ? MBEDTLS_BLOCK_CIPHER_ID_ARIA :
91               (cipher_id == MBEDTLS_CIPHER_ID_CAMELLIA) ? MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA :
92               MBEDTLS_BLOCK_CIPHER_ID_NONE;
93 
94 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
95     psa_key_type_t psa_key_type = psa_key_type_from_block_cipher_id(ctx->id);
96     if (psa_key_type != PSA_KEY_TYPE_NONE &&
97         psa_can_do_cipher(psa_key_type, PSA_ALG_ECB_NO_PADDING)) {
98         ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_PSA;
99         return 0;
100     }
101     ctx->engine = MBEDTLS_BLOCK_CIPHER_ENGINE_LEGACY;
102 #endif
103 
104     switch (ctx->id) {
105 #if defined(MBEDTLS_AES_C)
106         case MBEDTLS_BLOCK_CIPHER_ID_AES:
107             mbedtls_aes_init(&ctx->ctx.aes);
108             return 0;
109 #endif
110 #if defined(MBEDTLS_ARIA_C)
111         case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
112             mbedtls_aria_init(&ctx->ctx.aria);
113             return 0;
114 #endif
115 #if defined(MBEDTLS_CAMELLIA_C)
116         case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
117             mbedtls_camellia_init(&ctx->ctx.camellia);
118             return 0;
119 #endif
120         default:
121             ctx->id = MBEDTLS_BLOCK_CIPHER_ID_NONE;
122             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
123     }
124 }
125 
mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t * ctx,const unsigned char * key,unsigned key_bitlen)126 int mbedtls_block_cipher_setkey(mbedtls_block_cipher_context_t *ctx,
127                                 const unsigned char *key,
128                                 unsigned key_bitlen)
129 {
130 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
131     if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
132         psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
133         psa_status_t status;
134 
135         psa_set_key_type(&key_attr, psa_key_type_from_block_cipher_id(ctx->id));
136         psa_set_key_bits(&key_attr, key_bitlen);
137         psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
138         psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);
139 
140         status = psa_import_key(&key_attr, key, PSA_BITS_TO_BYTES(key_bitlen), &ctx->psa_key_id);
141         if (status != PSA_SUCCESS) {
142             return mbedtls_cipher_error_from_psa(status);
143         }
144         psa_reset_key_attributes(&key_attr);
145 
146         return 0;
147     }
148 #endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
149 
150     switch (ctx->id) {
151 #if defined(MBEDTLS_AES_C)
152         case MBEDTLS_BLOCK_CIPHER_ID_AES:
153             return mbedtls_aes_setkey_enc(&ctx->ctx.aes, key, key_bitlen);
154 #endif
155 #if defined(MBEDTLS_ARIA_C)
156         case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
157             return mbedtls_aria_setkey_enc(&ctx->ctx.aria, key, key_bitlen);
158 #endif
159 #if defined(MBEDTLS_CAMELLIA_C)
160         case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
161             return mbedtls_camellia_setkey_enc(&ctx->ctx.camellia, key, key_bitlen);
162 #endif
163         default:
164             return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
165     }
166 }
167 
mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t * ctx,const unsigned char input[16],unsigned char output[16])168 int mbedtls_block_cipher_encrypt(mbedtls_block_cipher_context_t *ctx,
169                                  const unsigned char input[16],
170                                  unsigned char output[16])
171 {
172 #if defined(MBEDTLS_BLOCK_CIPHER_SOME_PSA)
173     if (ctx->engine == MBEDTLS_BLOCK_CIPHER_ENGINE_PSA) {
174         psa_status_t status;
175         size_t olen;
176 
177         status = psa_cipher_encrypt(ctx->psa_key_id, PSA_ALG_ECB_NO_PADDING,
178                                     input, 16, output, 16, &olen);
179         if (status != PSA_SUCCESS) {
180             return mbedtls_cipher_error_from_psa(status);
181         }
182         return 0;
183     }
184 #endif /* MBEDTLS_BLOCK_CIPHER_SOME_PSA */
185 
186     switch (ctx->id) {
187 #if defined(MBEDTLS_AES_C)
188         case MBEDTLS_BLOCK_CIPHER_ID_AES:
189             return mbedtls_aes_crypt_ecb(&ctx->ctx.aes, MBEDTLS_AES_ENCRYPT,
190                                          input, output);
191 #endif
192 #if defined(MBEDTLS_ARIA_C)
193         case MBEDTLS_BLOCK_CIPHER_ID_ARIA:
194             return mbedtls_aria_crypt_ecb(&ctx->ctx.aria, input, output);
195 #endif
196 #if defined(MBEDTLS_CAMELLIA_C)
197         case MBEDTLS_BLOCK_CIPHER_ID_CAMELLIA:
198             return mbedtls_camellia_crypt_ecb(&ctx->ctx.camellia,
199                                               MBEDTLS_CAMELLIA_ENCRYPT,
200                                               input, output);
201 #endif
202         default:
203             return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT;
204     }
205 }
206 
207 #endif /* MBEDTLS_BLOCK_CIPHER_C */
208