1 /*
2  * Copyright (c) 2016 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Crypto Cipher structure definitions
10  *
11  * This file contains the Crypto Abstraction layer structures.
12  *
13  * [Experimental] Users should note that the Structures can change
14  * as a part of ongoing development.
15  */
16 
17 #ifndef ZEPHYR_INCLUDE_CRYPTO_CIPHER_STRUCTS_H_
18 #define ZEPHYR_INCLUDE_CRYPTO_CIPHER_STRUCTS_H_
19 
20 #include <device.h>
21 #include <sys/util.h>
22 /**
23  * @addtogroup crypto_cipher
24  * @{
25  */
26 
27 
28 /** Cipher Algorithm */
29 enum cipher_algo {
30 	CRYPTO_CIPHER_ALGO_AES = 1,
31 };
32 
33 /** Cipher Operation */
34 enum cipher_op {
35 	CRYPTO_CIPHER_OP_DECRYPT = 0,
36 	CRYPTO_CIPHER_OP_ENCRYPT = 1,
37 };
38 
39 /**
40  * Possible cipher mode options.
41  *
42  * More to be added as required.
43  */
44 enum cipher_mode {
45 	CRYPTO_CIPHER_MODE_ECB = 1,
46 	CRYPTO_CIPHER_MODE_CBC = 2,
47 	CRYPTO_CIPHER_MODE_CTR = 3,
48 	CRYPTO_CIPHER_MODE_CCM = 4,
49 	CRYPTO_CIPHER_MODE_GCM = 5,
50 };
51 
52 /* Forward declarations */
53 struct cipher_aead_pkt;
54 struct cipher_ctx;
55 struct cipher_pkt;
56 
57 typedef int (*block_op_t)(struct cipher_ctx *ctx, struct cipher_pkt *pkt);
58 
59 /* Function signatures for encryption/ decryption using standard cipher modes
60  * like  CBC, CTR, CCM.
61  */
62 typedef int (*cbc_op_t)(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
63 			uint8_t *iv);
64 
65 typedef int (*ctr_op_t)(struct cipher_ctx *ctx, struct cipher_pkt *pkt,
66 			uint8_t *ctr);
67 
68 typedef int (*ccm_op_t)(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt,
69 			 uint8_t *nonce);
70 
71 typedef int (*gcm_op_t)(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt,
72 			 uint8_t *nonce);
73 
74 struct cipher_ops {
75 
76 	enum cipher_mode cipher_mode;
77 
78 	union {
79 		block_op_t	block_crypt_hndlr;
80 		cbc_op_t	cbc_crypt_hndlr;
81 		ctr_op_t	ctr_crypt_hndlr;
82 		ccm_op_t	ccm_crypt_hndlr;
83 		gcm_op_t	gcm_crypt_hndlr;
84 	};
85 };
86 
87 struct ccm_params {
88 	uint16_t tag_len;
89 	uint16_t nonce_len;
90 };
91 
92 struct ctr_params {
93 	/* CTR mode counter is a split counter composed of iv and counter
94 	 * such that ivlen + ctr_len = keylen
95 	 */
96 	uint32_t ctr_len;
97 };
98 
99 struct gcm_params {
100 	uint16_t tag_len;
101 	uint16_t nonce_len;
102 };
103 
104 /**
105  * Structure encoding session parameters.
106  *
107  * Refer to comments for individual fields to know the contract
108  * in terms of who fills what and when w.r.t begin_session() call.
109  */
110 struct cipher_ctx {
111 
112 	/** Place for driver to return function pointers to be invoked per
113 	 * cipher operation. To be populated by crypto driver on return from
114 	 * begin_session() based on the algo/mode chosen by the app.
115 	 */
116 	struct cipher_ops ops;
117 
118 	/** To be populated by the app before calling begin_session() */
119 	union {
120 		/* Cryptographic key to be used in this session */
121 		uint8_t *bit_stream;
122 		/* For cases where  key is protected and is not
123 		 * available to caller
124 		 */
125 		void *handle;
126 	} key;
127 
128 	/** The device driver instance this crypto context relates to. Will be
129 	 * populated by the begin_session() API.
130 	 */
131 	const struct device *device;
132 
133 	/** If the driver supports multiple simultaneously crypto sessions, this
134 	 * will identify the specific driver state this crypto session relates
135 	 * to. Since dynamic memory allocation is not possible, it is
136 	 * suggested that at build time drivers allocate space for the
137 	 * max simultaneous sessions they intend to support. To be populated
138 	 * by the driver on return from begin_session().
139 	 */
140 	void *drv_sessn_state;
141 
142 	/** Place for the user app to put info relevant stuff for resuming when
143 	 * completion callback happens for async ops. Totally managed by the
144 	 * app.
145 	 */
146 	void *app_sessn_state;
147 
148 	/** Cypher mode parameters, which remain constant for all ops
149 	 * in a session. To be populated by the app before calling
150 	 * begin_session().
151 	 */
152 	union {
153 		struct ccm_params ccm_info;
154 		struct ctr_params ctr_info;
155 		struct gcm_params gcm_info;
156 	} mode_params;
157 
158 	/** Cryptographic keylength in bytes. To be populated by the app
159 	 * before calling begin_session()
160 	 */
161 	uint16_t  keylen;
162 
163 	/** How certain fields are to be interpreted for this session.
164 	 * (A bitmask of CAP_* below.)
165 	 * To be populated by the app before calling begin_session().
166 	 * An app can obtain the capability flags supported by a hw/driver
167 	 * by calling cipher_query_hwcaps().
168 	 */
169 	uint16_t flags;
170 };
171 
172 /* cipher_ctx.flags values. Not all drivers support all flags.
173  * A user app can query the supported hw / driver
174  * capabilities via provided API (cipher_query_hwcaps()), and choose a
175  * supported config during the session setup.
176  */
177 #define CAP_OPAQUE_KEY_HNDL		BIT(0)
178 #define CAP_RAW_KEY			BIT(1)
179 
180 /* TBD to define */
181 #define CAP_KEY_LOADING_API		BIT(2)
182 
183 /** Whether the output is placed in separate buffer or not */
184 #define CAP_INPLACE_OPS			BIT(3)
185 #define CAP_SEPARATE_IO_BUFS		BIT(4)
186 
187 /**
188  * These denotes if the output (completion of a cipher_xxx_op) is conveyed
189  * by the op function returning, or it is conveyed by an async notification
190  */
191 #define CAP_SYNC_OPS			BIT(5)
192 #define CAP_ASYNC_OPS			BIT(6)
193 
194 /** Whether the hardware/driver supports autononce feature */
195 #define CAP_AUTONONCE			BIT(7)
196 
197 /** Don't prefix IV to cipher blocks */
198 #define CAP_NO_IV_PREFIX		BIT(8)
199 
200 /* More flags to be added as necessary */
201 
202 
203 /**
204  * Structure encoding IO parameters of one cryptographic
205  * operation like encrypt/decrypt.
206  *
207  * The fields which has not been explicitly called out has to
208  * be filled up by the app before making the cipher_xxx_op()
209  * call.
210  */
211 struct cipher_pkt {
212 
213 	/** Start address of input buffer */
214 	uint8_t *in_buf;
215 
216 	/** Bytes to be operated upon */
217 	int  in_len;
218 
219 	/** Start of the output buffer, to be allocated by
220 	 * the application. Can be NULL for in-place ops. To be populated
221 	 * with contents by the driver on return from op / async callback.
222 	 */
223 	uint8_t *out_buf;
224 
225 	/** Size of the out_buf area allocated by the application. Drivers
226 	 * should not write past the size of output buffer.
227 	 */
228 	int out_buf_max;
229 
230 	/** To be populated by driver on return from cipher_xxx_op() and
231 	 * holds the size of the actual result.
232 	 */
233 	int out_len;
234 
235 	/** Context this packet relates to. This can be useful to get the
236 	 * session details, especially for async ops. Will be populated by the
237 	 * cipher_xxx_op() API based on the ctx parameter.
238 	 */
239 	struct cipher_ctx *ctx;
240 };
241 
242 /**
243  * Structure encoding IO parameters in AEAD (Authenticated Encryption
244  * with Associated Data) scenario like in CCM.
245  *
246  * App has to furnish valid contents prior to making cipher_ccm_op() call.
247  */
248 struct cipher_aead_pkt {
249 	/* IO buffers for encryption. This has to be supplied by the app. */
250 	struct cipher_pkt *pkt;
251 
252 	/**
253 	 * Start address for Associated Data. This has to be supplied by app.
254 	 */
255 	uint8_t *ad;
256 
257 	/** Size of  Associated Data. This has to be supplied by the app. */
258 	uint32_t ad_len;
259 
260 	/** Start address for the auth hash. For an encryption op this will
261 	 * be populated by the driver when it returns from cipher_ccm_op call.
262 	 * For a decryption op this has to be supplied by the app.
263 	 */
264 	uint8_t *tag;
265 };
266 
267 /* Prototype for the application function to be invoked by the crypto driver
268  * on completion of an async request. The app may get the session context
269  * via the pkt->ctx field. For CCM ops the encompassing AEAD packet may be
270  * accessed via container_of(). The type of a packet can be determined via
271  * pkt->ctx.ops.mode .
272  */
273 typedef void (*crypto_completion_cb)(struct cipher_pkt *completed, int status);
274 
275 /**
276  * @}
277  */
278 #endif /* ZEPHYR_INCLUDE_CRYPTO_CIPHER_STRUCTS_H_ */
279