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