1 From 501988587567b996c9c4a14239f575e77ed27791 Mon Sep 17 00:00:00 2001
2 From: Pankaj Gupta <pankaj.gupta@nxp.com>
3 Date: Fri, 20 Sep 2019 12:18:16 +0530
4 Subject: [PATCH 1/2] eng_devcrypto: add support for TLS algorithms offload
6 - aes-128-cbc-hmac-sha1
7 - aes-256-cbc-hmac-sha1
9 Requires TLS patches on cryptodev and TLS algorithm support in Linux
12 Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
14 crypto/engine/eng_devcrypto.c | 265 +++++++++++++++++++++++++++++-----
15 1 file changed, 231 insertions(+), 34 deletions(-)
17 diff --git a/crypto/engine/eng_devcrypto.c b/crypto/engine/eng_devcrypto.c
18 index 49e9ce1af3..727a660e75 100644
19 --- a/crypto/engine/eng_devcrypto.c
20 +++ b/crypto/engine/eng_devcrypto.c
21 @@ -60,6 +60,9 @@ struct cipher_ctx {
22 struct session_op sess;
23 int op; /* COP_ENCRYPT or COP_DECRYPT */
24 unsigned long mode; /* EVP_CIPH_*_MODE */
26 + unsigned int aad_len;
29 /* to handle ctr mode being a stream cipher */
30 unsigned char partial[EVP_MAX_BLOCK_LENGTH];
31 @@ -73,49 +76,62 @@ static const struct cipher_data_st {
37 #ifndef OPENSSL_NO_DES
38 - { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC },
39 - { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC },
40 + { NID_des_cbc, 8, 8, 8, EVP_CIPH_CBC_MODE, CRYPTO_DES_CBC, 0 },
41 + { NID_des_ede3_cbc, 8, 24, 8, EVP_CIPH_CBC_MODE, CRYPTO_3DES_CBC, 0 },
44 - { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC },
45 + { NID_bf_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_BLF_CBC, 0 },
47 #ifndef OPENSSL_NO_CAST
48 - { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC },
49 + { NID_cast5_cbc, 8, 16, 8, EVP_CIPH_CBC_MODE, CRYPTO_CAST_CBC, 0 },
51 - { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
52 - { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
53 - { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC },
54 + { NID_aes_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC, 0 },
55 + { NID_aes_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC, 0 },
56 + { NID_aes_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE, CRYPTO_AES_CBC, 0 },
57 + { NID_aes_128_cbc_hmac_sha1, 16, 16, 16,
58 + EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_AEAD_CIPHER,
59 + CRYPTO_TLS10_AES_CBC_HMAC_SHA1, 20 },
60 + { NID_aes_256_cbc_hmac_sha1, 16, 32, 16,
61 + EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_AEAD_CIPHER,
62 + CRYPTO_TLS10_AES_CBC_HMAC_SHA1, 20 },
63 #ifndef OPENSSL_NO_RC4
64 - { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4 },
65 + { NID_rc4, 1, 16, 0, EVP_CIPH_STREAM_CIPHER, CRYPTO_ARC4, 0 },
67 #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_CTR)
68 - { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
69 - { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
70 - { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR },
71 + { NID_aes_128_ctr, 16, 128 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR, 0 },
72 + { NID_aes_192_ctr, 16, 192 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR, 0 },
73 + { NID_aes_256_ctr, 16, 256 / 8, 16, EVP_CIPH_CTR_MODE, CRYPTO_AES_CTR, 0 },
75 #if 0 /* Not yet supported */
76 - { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
77 - { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS },
78 + { NID_aes_128_xts, 16, 128 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS,
80 + { NID_aes_256_xts, 16, 256 / 8 * 2, 16, EVP_CIPH_XTS_MODE, CRYPTO_AES_XTS,
83 #if !defined(CHECK_BSD_STYLE_MACROS) || defined(CRYPTO_AES_ECB)
84 - { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
85 - { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
86 - { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB },
87 + { NID_aes_128_ecb, 16, 128 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB, 0 },
88 + { NID_aes_192_ecb, 16, 192 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB, 0 },
89 + { NID_aes_256_ecb, 16, 256 / 8, 0, EVP_CIPH_ECB_MODE, CRYPTO_AES_ECB, 0 },
91 #if 0 /* Not yet supported */
92 - { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
93 - { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
94 - { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM },
95 + { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
96 + { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
97 + { NID_aes_256_gcm, 16, 256 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
99 +#ifdef OPENSSL_NXP_CAAM
100 + { NID_aes_128_gcm, 16, 128 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
101 + { NID_aes_192_gcm, 16, 192 / 8, 16, EVP_CIPH_GCM_MODE, CRYPTO_AES_GCM, 0 },
103 #ifndef OPENSSL_NO_CAMELLIA
104 { NID_camellia_128_cbc, 16, 128 / 8, 16, EVP_CIPH_CBC_MODE,
105 - CRYPTO_CAMELLIA_CBC },
106 + CRYPTO_CAMELLIA_CBC, 0 },
107 { NID_camellia_192_cbc, 16, 192 / 8, 16, EVP_CIPH_CBC_MODE,
108 - CRYPTO_CAMELLIA_CBC },
109 + CRYPTO_CAMELLIA_CBC, 0 },
110 { NID_camellia_256_cbc, 16, 256 / 8, 16, EVP_CIPH_CBC_MODE,
111 - CRYPTO_CAMELLIA_CBC },
112 + CRYPTO_CAMELLIA_CBC, 0 },
116 @@ -141,6 +157,158 @@ static const struct cipher_data_st *get_cipher_data(int nid)
117 return &cipher_data[get_cipher_data_index(nid)];
121 + * Save the encryption key provided by upper layers. This function is called
122 + * by EVP_CipherInit_ex to initialize the algorithm's extra data. We can't do
123 + * much here because the mac key is not available. The next call should/will
124 + * be to cryptodev_cbc_hmac_sha1_ctrl with parameter
125 + * EVP_CTRL_AEAD_SET_MAC_KEY, to set the hmac key. There we call CIOCGSESSION
126 + * with both the crypto and hmac keys.
128 +static int cryptodev_init_aead_key(EVP_CIPHER_CTX *ctx,
129 + const unsigned char *key, const unsigned char *iv, int enc)
131 + struct cipher_ctx *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
132 + struct session_op *sess = &state->sess;
133 + int cipher = -1, i;
135 + for (i = 0; cipher_data[i].devcryptoid; i++) {
136 + if (EVP_CIPHER_CTX_nid(ctx) == cipher_data[i].nid &&
137 + EVP_CIPHER_CTX_iv_length(ctx) <= cipher_data[i].ivlen &&
138 + EVP_CIPHER_CTX_key_length(ctx) == cipher_data[i].keylen) {
139 + cipher = cipher_data[i].devcryptoid;
144 + if (!cipher_data[i].devcryptoid)
147 + memset(sess, 0, sizeof(*sess));
149 + sess->key = (void *) key;
150 + sess->keylen = EVP_CIPHER_CTX_key_length(ctx);
151 + sess->cipher = cipher;
153 + /* for whatever reason, (1) means success */
157 +static int cryptodev_aead_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
158 + const unsigned char *in, size_t len)
160 + struct crypt_auth_op cryp;
161 + struct cipher_ctx *state = EVP_CIPHER_CTX_get_cipher_data(ctx);
162 + struct session_op *sess = &state->sess;
164 + unsigned char save_iv[EVP_MAX_IV_LENGTH];
170 + if ((len % EVP_CIPHER_CTX_block_size(ctx)) != 0)
173 + memset(&cryp, 0, sizeof(cryp));
175 + /* TODO: make a seamless integration with cryptodev flags */
176 + switch (EVP_CIPHER_CTX_nid(ctx)) {
177 + case NID_aes_128_cbc_hmac_sha1:
178 + case NID_aes_256_cbc_hmac_sha1:
179 + cryp.flags = COP_FLAG_AEAD_TLS_TYPE;
181 + cryp.ses = sess->ses;
182 + cryp.len = state->len;
183 + cryp.src = (void *) in;
184 + cryp.dst = (void *) out;
185 + cryp.auth_src = state->aad;
186 + cryp.auth_len = state->aad_len;
188 + cryp.op = EVP_CIPHER_CTX_encrypting(ctx) ? COP_ENCRYPT : COP_DECRYPT;
190 + if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
191 + cryp.iv = (void *) EVP_CIPHER_CTX_iv(ctx);
192 + if (!EVP_CIPHER_CTX_encrypting(ctx)) {
193 + iiv = in + len - EVP_CIPHER_CTX_iv_length(ctx);
194 + memcpy(save_iv, iiv, EVP_CIPHER_CTX_iv_length(ctx));
199 + if (ioctl(cfd, CIOCAUTHCRYPT, &cryp) == -1) {
201 + * XXX need better errror handling this can fail for a number of
202 + * different reasons.
207 + if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
208 + if (EVP_CIPHER_CTX_encrypting(ctx))
209 + iiv = out + len - EVP_CIPHER_CTX_iv_length(ctx);
213 + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iiv,
214 + EVP_CIPHER_CTX_iv_length(ctx));
219 +static int cryptodev_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type,
220 + int arg, void *ptr)
223 + case EVP_CTRL_AEAD_SET_MAC_KEY:
225 + /* TODO: what happens with hmac keys larger than 64 bytes? */
226 + struct cipher_ctx *state =
227 + EVP_CIPHER_CTX_get_cipher_data(ctx);
228 + struct session_op *sess = &state->sess;
230 + /* the rest should have been set in cryptodev_init_aead_key */
231 + sess->mackey = ptr;
232 + sess->mackeylen = arg;
233 + if (ioctl(cfd, CIOCGSESSION, sess) == -1)
238 + case EVP_CTRL_AEAD_TLS1_AAD:
240 + /* ptr points to the associated data buffer of 13 bytes */
241 + struct cipher_ctx *state =
242 + EVP_CIPHER_CTX_get_cipher_data(ctx);
243 + unsigned char *p = ptr;
244 + unsigned int cryptlen = p[arg - 2] << 8 | p[arg - 1];
245 + unsigned int maclen, padlen;
246 + unsigned int bs = EVP_CIPHER_CTX_block_size(ctx);
249 + state->aad_len = arg;
250 + state->len = cryptlen;
252 + /* TODO: this should be an extension of EVP_CIPHER struct */
253 + switch (EVP_CIPHER_CTX_nid(ctx)) {
254 + case NID_aes_128_cbc_hmac_sha1:
255 + case NID_aes_256_cbc_hmac_sha1:
256 + maclen = SHA_DIGEST_LENGTH;
259 + /* space required for encryption (not only TLS padding) */
261 + if (EVP_CIPHER_CTX_encrypting(ctx)) {
262 + cryptlen += maclen;
263 + padlen += bs - (cryptlen % bs);
273 * Following are the three necessary functions to map OpenSSL functionality
275 @@ -165,6 +333,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
276 cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
277 cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE;
278 cipher_ctx->blocksize = cipher_d->blocksize;
280 if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
281 SYSerr(SYS_F_IOCTL, errno);
283 @@ -180,6 +349,7 @@ static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
284 (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
285 struct crypt_op cryp;
286 unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
288 #if !defined(COP_FLAG_WRITE_IV)
289 unsigned char saved_iv[EVP_MAX_IV_LENGTH];
290 const unsigned char *ivptr;
291 @@ -340,32 +510,59 @@ static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
292 static int known_cipher_nids[OSSL_NELEM(cipher_data)];
293 static int known_cipher_nids_amount = -1; /* -1 indicates not yet initialised */
294 static EVP_CIPHER *known_cipher_methods[OSSL_NELEM(cipher_data)] = { NULL, };
295 +int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key,
296 + const unsigned char *iv, int enc);
297 +int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out,
298 + const unsigned char *in, size_t inl);
299 +int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr);
301 static void prepare_cipher_methods(void)
304 struct session_op sess;
305 unsigned long cipher_mode;
306 + unsigned long flags;
308 memset(&sess, 0, sizeof(sess));
309 sess.key = (void *)"01234567890123456789012345678901234567890123456789";
310 + sess.mackey = (void *)"123456789ABCDEFGHIJKLMNO";
312 for (i = 0, known_cipher_nids_amount = 0;
313 i < OSSL_NELEM(cipher_data); i++) {
315 + init = cipher_init;
316 + ctrl = cipher_ctrl;
317 + flags = cipher_data[i].flags
318 + | EVP_CIPH_CUSTOM_COPY
319 + | EVP_CIPH_CTRL_INIT
320 + | EVP_CIPH_FLAG_DEFAULT_ASN1;
323 * Check that the algo is really availably by trying to open and close
326 sess.cipher = cipher_data[i].devcryptoid;
327 sess.keylen = cipher_data[i].keylen;
328 + sess.mackeylen = cipher_data[i].mackeylen;
330 + cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
332 + do_cipher = (cipher_mode == EVP_CIPH_CTR_MODE ?
335 + if (cipher_data[i].nid == NID_aes_128_cbc_hmac_sha1
336 + || cipher_data[i].nid == NID_aes_256_cbc_hmac_sha1) {
337 + init = cryptodev_init_aead_key;
338 + do_cipher = cryptodev_aead_cipher;
339 + ctrl = cryptodev_cbc_hmac_sha1_ctrl;
340 + flags = cipher_data[i].flags;
343 if (ioctl(cfd, CIOCGSESSION, &sess) < 0
344 || ioctl(cfd, CIOCFSESSION, &sess.ses) < 0)
347 - cipher_mode = cipher_data[i].flags & EVP_CIPH_MODE;
349 - if ((known_cipher_methods[i] =
350 + if ((known_cipher_methods[i] =
351 EVP_CIPHER_meth_new(cipher_data[i].nid,
352 cipher_mode == EVP_CIPH_CTR_MODE ? 1 :
353 cipher_data[i].blocksize,
354 @@ -373,16 +570,12 @@ static void prepare_cipher_methods(void)
355 || !EVP_CIPHER_meth_set_iv_length(known_cipher_methods[i],
356 cipher_data[i].ivlen)
357 || !EVP_CIPHER_meth_set_flags(known_cipher_methods[i],
358 - cipher_data[i].flags
359 - | EVP_CIPH_CUSTOM_COPY
360 - | EVP_CIPH_CTRL_INIT
361 - | EVP_CIPH_FLAG_DEFAULT_ASN1)
362 - || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], cipher_init)
364 + || !EVP_CIPHER_meth_set_init(known_cipher_methods[i], init)
365 || !EVP_CIPHER_meth_set_do_cipher(known_cipher_methods[i],
366 - cipher_mode == EVP_CIPH_CTR_MODE ?
369 - || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], cipher_ctrl)
371 + /* AEAD Support to be added. */
372 + || !EVP_CIPHER_meth_set_ctrl(known_cipher_methods[i], ctrl)
373 || !EVP_CIPHER_meth_set_cleanup(known_cipher_methods[i],
375 || !EVP_CIPHER_meth_set_impl_ctx_size(known_cipher_methods[i],
376 @@ -393,6 +586,10 @@ static void prepare_cipher_methods(void)
377 known_cipher_nids[known_cipher_nids_amount++] =
381 + if (cipher_data[i].nid == NID_aes_128_cbc_hmac_sha1
382 + || cipher_data[i].nid == NID_aes_256_cbc_hmac_sha1)
383 + EVP_add_cipher(known_cipher_methods[i]);