1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
4 */
5
6 #include <assert.h>
7 #include <crypto/crypto.h>
8 #include <crypto/crypto_impl.h>
9 #include <drvcrypt.h>
10 #include <drvcrypt_cipher.h>
11 #include <kernel/dt.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <tee_api_types.h>
15 #include <util.h>
16
17 #include "common.h"
18 #include "stm32_cryp.h"
19
20 #define DES3_KEY_SIZE 24
21
22 struct stm32_cipher_ctx {
23 struct crypto_cipher_ctx c_ctx;
24 struct stm32_cryp_context cryp;
25 enum stm32_cryp_algo_mode algo;
26 };
27
28 static struct stm32_cipher_ctx *
to_stm32_cipher_ctx(struct crypto_cipher_ctx * ctx)29 to_stm32_cipher_ctx(struct crypto_cipher_ctx *ctx)
30 {
31 assert(ctx);
32
33 return container_of(ctx, struct stm32_cipher_ctx, c_ctx);
34 }
35
stm32_cipher_initialize(struct drvcrypt_cipher_init * dinit)36 static TEE_Result stm32_cipher_initialize(struct drvcrypt_cipher_init *dinit)
37 {
38 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dinit->ctx);
39 uint8_t temp_key[DES3_KEY_SIZE] = { 0 };
40 uint8_t *key = NULL;
41 size_t key_size = 0;
42
43 if (dinit->key1.length == 16 &&
44 (c->algo == STM32_CRYP_MODE_TDES_ECB ||
45 c->algo == STM32_CRYP_MODE_TDES_CBC)) {
46 /* Manage DES2: ie K=K1.K2.K1 */
47 memcpy(temp_key, dinit->key1.data, dinit->key1.length);
48 memcpy(temp_key + dinit->key1.length, dinit->key1.data,
49 dinit->key1.length / 2);
50 key_size = DES3_KEY_SIZE;
51 key = temp_key;
52 } else {
53 key_size = dinit->key1.length;
54 key = dinit->key1.data;
55 }
56
57 return stm32_cryp_init(&c->cryp, !dinit->encrypt, c->algo,
58 key, key_size, dinit->iv.data,
59 dinit->iv.length);
60 }
61
stm32_cipher_update(struct drvcrypt_cipher_update * dupdate)62 static TEE_Result stm32_cipher_update(struct drvcrypt_cipher_update *dupdate)
63 {
64 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(dupdate->ctx);
65 size_t len = MIN(dupdate->src.length, dupdate->dst.length);
66
67 return stm32_cryp_update(&c->cryp, dupdate->last,
68 dupdate->src.data, dupdate->dst.data,
69 len);
70 }
71
stm32_cipher_final(void * ctx __unused)72 static void stm32_cipher_final(void *ctx __unused)
73 {
74 }
75
stm32_cipher_free(void * ctx)76 static void stm32_cipher_free(void *ctx)
77 {
78 struct stm32_cipher_ctx *c = to_stm32_cipher_ctx(ctx);
79
80 free(c);
81 }
82
stm32_cipher_copy_state(void * dst_ctx,void * src_ctx)83 static void stm32_cipher_copy_state(void *dst_ctx, void *src_ctx)
84 {
85 struct stm32_cipher_ctx *src = to_stm32_cipher_ctx(src_ctx);
86 struct stm32_cipher_ctx *dst = to_stm32_cipher_ctx(dst_ctx);
87
88 memcpy(dst, src, sizeof(*dst));
89 }
90
alloc_ctx(void ** ctx,enum stm32_cryp_algo_mode algo)91 static TEE_Result alloc_ctx(void **ctx, enum stm32_cryp_algo_mode algo)
92 {
93 struct stm32_cipher_ctx *c = calloc(1, sizeof(*c));
94
95 if (!c)
96 return TEE_ERROR_OUT_OF_MEMORY;
97
98 c->algo = algo;
99 *ctx = &c->c_ctx;
100
101 return TEE_SUCCESS;
102 }
103
104 /*
105 * Allocate the SW cipher data context.
106 *
107 * @ctx [out] Caller context variable
108 * @algo Algorithm ID of the context
109 */
stm32_cipher_allocate(void ** ctx,uint32_t algo)110 static TEE_Result stm32_cipher_allocate(void **ctx, uint32_t algo)
111 {
112 /*
113 * Convert TEE_ALGO id to internal id
114 */
115 switch (algo) {
116 case TEE_ALG_DES_ECB_NOPAD:
117 return alloc_ctx(ctx, STM32_CRYP_MODE_DES_ECB);
118 case TEE_ALG_DES_CBC_NOPAD:
119 return alloc_ctx(ctx, STM32_CRYP_MODE_DES_CBC);
120 case TEE_ALG_DES3_ECB_NOPAD:
121 return alloc_ctx(ctx, STM32_CRYP_MODE_TDES_ECB);
122 case TEE_ALG_DES3_CBC_NOPAD:
123 return alloc_ctx(ctx, STM32_CRYP_MODE_TDES_CBC);
124 case TEE_ALG_AES_ECB_NOPAD:
125 return alloc_ctx(ctx, STM32_CRYP_MODE_AES_ECB);
126 case TEE_ALG_AES_CBC_NOPAD:
127 return alloc_ctx(ctx, STM32_CRYP_MODE_AES_CBC);
128 case TEE_ALG_AES_CTR:
129 return alloc_ctx(ctx, STM32_CRYP_MODE_AES_CTR);
130 default:
131 return TEE_ERROR_NOT_IMPLEMENTED;
132 }
133 }
134
135 static struct drvcrypt_cipher driver_cipher = {
136 .alloc_ctx = &stm32_cipher_allocate,
137 .free_ctx = &stm32_cipher_free,
138 .init = &stm32_cipher_initialize,
139 .update = &stm32_cipher_update,
140 .final = &stm32_cipher_final,
141 .copy_state = &stm32_cipher_copy_state,
142 };
143
stm32_register_cipher(void)144 TEE_Result stm32_register_cipher(void)
145 {
146 return drvcrypt_register_cipher(&driver_cipher);
147 }
148