Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/crypto/caam/caamalg_desc.c
26288 views
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
* Shared descriptors for aead, skcipher algorithms
4
*
5
* Copyright 2016-2019 NXP
6
*/
7
8
#include "compat.h"
9
#include "desc_constr.h"
10
#include "caamalg_desc.h"
11
12
/*
13
* For aead functions, read payload and write payload,
14
* both of which are specified in req->src and req->dst
15
*/
16
static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
17
{
18
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
19
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
20
KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
21
}
22
23
/* Set DK bit in class 1 operation if shared */
24
static inline void append_dec_op1(u32 *desc, u32 type)
25
{
26
u32 *jump_cmd, *uncond_jump_cmd;
27
28
/* DK bit is valid only for AES */
29
if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
30
append_operation(desc, type | OP_ALG_AS_INITFINAL |
31
OP_ALG_DECRYPT);
32
return;
33
}
34
35
jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
36
append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT);
37
uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
38
set_jump_tgt_here(desc, jump_cmd);
39
append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT |
40
OP_ALG_AAI_DK);
41
set_jump_tgt_here(desc, uncond_jump_cmd);
42
}
43
44
/**
45
* cnstr_shdsc_aead_null_encap - IPSec ESP encapsulation shared descriptor
46
* (non-protocol) with no (null) encryption.
47
* @desc: pointer to buffer used for descriptor construction
48
* @adata: pointer to authentication transform definitions.
49
* A split key is required for SEC Era < 6; the size of the split key
50
* is specified in this case. Valid algorithm values - one of
51
* OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
52
* with OP_ALG_AAI_HMAC_PRECOMP.
53
* @icvsize: integrity check value (ICV) size (truncated or full)
54
* @era: SEC Era
55
*/
56
void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
57
unsigned int icvsize, int era)
58
{
59
u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
60
61
init_sh_desc(desc, HDR_SHARE_SERIAL);
62
63
/* Skip if already shared */
64
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
65
JUMP_COND_SHRD);
66
if (era < 6) {
67
if (adata->key_inline)
68
append_key_as_imm(desc, adata->key_virt,
69
adata->keylen_pad, adata->keylen,
70
CLASS_2 | KEY_DEST_MDHA_SPLIT |
71
KEY_ENC);
72
else
73
append_key(desc, adata->key_dma, adata->keylen,
74
CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
75
} else {
76
append_proto_dkp(desc, adata);
77
}
78
set_jump_tgt_here(desc, key_jump_cmd);
79
80
/* assoclen + cryptlen = seqinlen */
81
append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
82
83
/* Prepare to read and write cryptlen + assoclen bytes */
84
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
85
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
86
87
/*
88
* MOVE_LEN opcode is not available in all SEC HW revisions,
89
* thus need to do some magic, i.e. self-patch the descriptor
90
* buffer.
91
*/
92
read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
93
MOVE_DEST_MATH3 |
94
(0x6 << MOVE_LEN_SHIFT));
95
write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
96
MOVE_DEST_DESCBUF |
97
MOVE_WAITCOMP |
98
(0x8 << MOVE_LEN_SHIFT));
99
100
/* Class 2 operation */
101
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
102
OP_ALG_ENCRYPT);
103
104
/* Read and write cryptlen bytes */
105
aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
106
107
set_move_tgt_here(desc, read_move_cmd);
108
set_move_tgt_here(desc, write_move_cmd);
109
append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
110
append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
111
MOVE_AUX_LS);
112
113
/* Write ICV */
114
append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
115
LDST_SRCDST_BYTE_CONTEXT);
116
117
print_hex_dump_debug("aead null enc shdesc@" __stringify(__LINE__)": ",
118
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
119
1);
120
}
121
EXPORT_SYMBOL(cnstr_shdsc_aead_null_encap);
122
123
/**
124
* cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
125
* (non-protocol) with no (null) decryption.
126
* @desc: pointer to buffer used for descriptor construction
127
* @adata: pointer to authentication transform definitions.
128
* A split key is required for SEC Era < 6; the size of the split key
129
* is specified in this case. Valid algorithm values - one of
130
* OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
131
* with OP_ALG_AAI_HMAC_PRECOMP.
132
* @icvsize: integrity check value (ICV) size (truncated or full)
133
* @era: SEC Era
134
*/
135
void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
136
unsigned int icvsize, int era)
137
{
138
u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
139
140
init_sh_desc(desc, HDR_SHARE_SERIAL);
141
142
/* Skip if already shared */
143
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
144
JUMP_COND_SHRD);
145
if (era < 6) {
146
if (adata->key_inline)
147
append_key_as_imm(desc, adata->key_virt,
148
adata->keylen_pad, adata->keylen,
149
CLASS_2 | KEY_DEST_MDHA_SPLIT |
150
KEY_ENC);
151
else
152
append_key(desc, adata->key_dma, adata->keylen,
153
CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
154
} else {
155
append_proto_dkp(desc, adata);
156
}
157
set_jump_tgt_here(desc, key_jump_cmd);
158
159
/* Class 2 operation */
160
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
161
OP_ALG_DECRYPT | OP_ALG_ICV_ON);
162
163
/* assoclen + cryptlen = seqoutlen */
164
append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
165
166
/* Prepare to read and write cryptlen + assoclen bytes */
167
append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
168
append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
169
170
/*
171
* MOVE_LEN opcode is not available in all SEC HW revisions,
172
* thus need to do some magic, i.e. self-patch the descriptor
173
* buffer.
174
*/
175
read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
176
MOVE_DEST_MATH2 |
177
(0x6 << MOVE_LEN_SHIFT));
178
write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
179
MOVE_DEST_DESCBUF |
180
MOVE_WAITCOMP |
181
(0x8 << MOVE_LEN_SHIFT));
182
183
/* Read and write cryptlen bytes */
184
aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
185
186
/*
187
* Insert a NOP here, since we need at least 4 instructions between
188
* code patching the descriptor buffer and the location being patched.
189
*/
190
jump_cmd = append_jump(desc, JUMP_TEST_ALL);
191
set_jump_tgt_here(desc, jump_cmd);
192
193
set_move_tgt_here(desc, read_move_cmd);
194
set_move_tgt_here(desc, write_move_cmd);
195
append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
196
append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
197
MOVE_AUX_LS);
198
append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
199
200
/* Load ICV */
201
append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
202
FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
203
204
print_hex_dump_debug("aead null dec shdesc@" __stringify(__LINE__)": ",
205
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
206
1);
207
}
208
EXPORT_SYMBOL(cnstr_shdsc_aead_null_decap);
209
210
static void init_sh_desc_key_aead(u32 * const desc,
211
struct alginfo * const cdata,
212
struct alginfo * const adata,
213
const bool is_rfc3686, u32 *nonce, int era)
214
{
215
u32 *key_jump_cmd;
216
unsigned int enckeylen = cdata->keylen;
217
218
/* Note: Context registers are saved. */
219
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
220
221
/* Skip if already shared */
222
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
223
JUMP_COND_SHRD);
224
225
/*
226
* RFC3686 specific:
227
* | key = {AUTH_KEY, ENC_KEY, NONCE}
228
* | enckeylen = encryption key size + nonce size
229
*/
230
if (is_rfc3686)
231
enckeylen -= CTR_RFC3686_NONCE_SIZE;
232
233
if (era < 6) {
234
if (adata->key_inline)
235
append_key_as_imm(desc, adata->key_virt,
236
adata->keylen_pad, adata->keylen,
237
CLASS_2 | KEY_DEST_MDHA_SPLIT |
238
KEY_ENC);
239
else
240
append_key(desc, adata->key_dma, adata->keylen,
241
CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
242
} else {
243
append_proto_dkp(desc, adata);
244
}
245
246
if (cdata->key_inline)
247
append_key_as_imm(desc, cdata->key_virt, enckeylen,
248
enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
249
else
250
append_key(desc, cdata->key_dma, enckeylen, CLASS_1 |
251
KEY_DEST_CLASS_REG);
252
253
/* Load Counter into CONTEXT1 reg */
254
if (is_rfc3686) {
255
append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
256
LDST_CLASS_IND_CCB |
257
LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
258
append_move(desc,
259
MOVE_SRC_OUTFIFO |
260
MOVE_DEST_CLASS1CTX |
261
(16 << MOVE_OFFSET_SHIFT) |
262
(CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
263
}
264
265
set_jump_tgt_here(desc, key_jump_cmd);
266
}
267
268
/**
269
* cnstr_shdsc_aead_encap - IPSec ESP encapsulation shared descriptor
270
* (non-protocol).
271
* @desc: pointer to buffer used for descriptor construction
272
* @cdata: pointer to block cipher transform definitions
273
* Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
274
* with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
275
* @adata: pointer to authentication transform definitions.
276
* A split key is required for SEC Era < 6; the size of the split key
277
* is specified in this case. Valid algorithm values - one of
278
* OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
279
* with OP_ALG_AAI_HMAC_PRECOMP.
280
* @ivsize: initialization vector size
281
* @icvsize: integrity check value (ICV) size (truncated or full)
282
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
283
* @nonce: pointer to rfc3686 nonce
284
* @ctx1_iv_off: IV offset in CONTEXT1 register
285
* @is_qi: true when called from caam/qi
286
* @era: SEC Era
287
*/
288
void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
289
struct alginfo *adata, unsigned int ivsize,
290
unsigned int icvsize, const bool is_rfc3686,
291
u32 *nonce, const u32 ctx1_iv_off, const bool is_qi,
292
int era)
293
{
294
/* Note: Context registers are saved. */
295
init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
296
297
/* Class 2 operation */
298
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
299
OP_ALG_ENCRYPT);
300
301
if (is_qi) {
302
u32 *wait_load_cmd;
303
304
/* REG3 = assoclen */
305
append_seq_load(desc, 4, LDST_CLASS_DECO |
306
LDST_SRCDST_WORD_DECO_MATH3 |
307
(4 << LDST_OFFSET_SHIFT));
308
309
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
310
JUMP_COND_CALM | JUMP_COND_NCP |
311
JUMP_COND_NOP | JUMP_COND_NIP |
312
JUMP_COND_NIFP);
313
set_jump_tgt_here(desc, wait_load_cmd);
314
315
append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
316
LDST_SRCDST_BYTE_CONTEXT |
317
(ctx1_iv_off << LDST_OFFSET_SHIFT));
318
}
319
320
/* Read and write assoclen bytes */
321
if (is_qi || era < 3) {
322
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
323
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
324
} else {
325
append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
326
append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
327
}
328
329
/* Skip assoc data */
330
append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
331
332
/* read assoc before reading payload */
333
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
334
FIFOLDST_VLF);
335
336
/* Load Counter into CONTEXT1 reg */
337
if (is_rfc3686)
338
append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
339
LDST_SRCDST_BYTE_CONTEXT |
340
((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
341
LDST_OFFSET_SHIFT));
342
343
/* Class 1 operation */
344
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
345
OP_ALG_ENCRYPT);
346
347
/* Read and write cryptlen bytes */
348
append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
349
append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
350
aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
351
352
/* Write ICV */
353
append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
354
LDST_SRCDST_BYTE_CONTEXT);
355
356
print_hex_dump_debug("aead enc shdesc@" __stringify(__LINE__)": ",
357
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
358
1);
359
}
360
EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
361
362
/**
363
* cnstr_shdsc_aead_decap - IPSec ESP decapsulation shared descriptor
364
* (non-protocol).
365
* @desc: pointer to buffer used for descriptor construction
366
* @cdata: pointer to block cipher transform definitions
367
* Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
368
* with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
369
* @adata: pointer to authentication transform definitions.
370
* A split key is required for SEC Era < 6; the size of the split key
371
* is specified in this case. Valid algorithm values - one of
372
* OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
373
* with OP_ALG_AAI_HMAC_PRECOMP.
374
* @ivsize: initialization vector size
375
* @icvsize: integrity check value (ICV) size (truncated or full)
376
* @geniv: whether to generate Encrypted Chain IV
377
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
378
* @nonce: pointer to rfc3686 nonce
379
* @ctx1_iv_off: IV offset in CONTEXT1 register
380
* @is_qi: true when called from caam/qi
381
* @era: SEC Era
382
*/
383
void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
384
struct alginfo *adata, unsigned int ivsize,
385
unsigned int icvsize, const bool geniv,
386
const bool is_rfc3686, u32 *nonce,
387
const u32 ctx1_iv_off, const bool is_qi, int era)
388
{
389
/* Note: Context registers are saved. */
390
init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
391
392
/* Class 2 operation */
393
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
394
OP_ALG_DECRYPT | OP_ALG_ICV_ON);
395
396
if (is_qi) {
397
u32 *wait_load_cmd;
398
399
/* REG3 = assoclen */
400
append_seq_load(desc, 4, LDST_CLASS_DECO |
401
LDST_SRCDST_WORD_DECO_MATH3 |
402
(4 << LDST_OFFSET_SHIFT));
403
404
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
405
JUMP_COND_CALM | JUMP_COND_NCP |
406
JUMP_COND_NOP | JUMP_COND_NIP |
407
JUMP_COND_NIFP);
408
set_jump_tgt_here(desc, wait_load_cmd);
409
410
if (!geniv)
411
append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
412
LDST_SRCDST_BYTE_CONTEXT |
413
(ctx1_iv_off << LDST_OFFSET_SHIFT));
414
}
415
416
/* Read and write assoclen bytes */
417
if (is_qi || era < 3) {
418
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
419
if (geniv)
420
append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
421
ivsize);
422
else
423
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
424
CAAM_CMD_SZ);
425
} else {
426
append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
427
if (geniv)
428
append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
429
ivsize);
430
else
431
append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
432
CAAM_CMD_SZ);
433
}
434
435
/* Skip assoc data */
436
append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
437
438
/* read assoc before reading payload */
439
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
440
KEY_VLF);
441
442
if (geniv) {
443
append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
444
LDST_SRCDST_BYTE_CONTEXT |
445
(ctx1_iv_off << LDST_OFFSET_SHIFT));
446
append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
447
(ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
448
}
449
450
/* Load Counter into CONTEXT1 reg */
451
if (is_rfc3686)
452
append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
453
LDST_SRCDST_BYTE_CONTEXT |
454
((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
455
LDST_OFFSET_SHIFT));
456
457
/* Choose operation */
458
if (ctx1_iv_off)
459
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
460
OP_ALG_DECRYPT);
461
else
462
append_dec_op1(desc, cdata->algtype);
463
464
/* Read and write cryptlen bytes */
465
append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
466
append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
467
aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
468
469
/* Load ICV */
470
append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
471
FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
472
473
print_hex_dump_debug("aead dec shdesc@" __stringify(__LINE__)": ",
474
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
475
1);
476
}
477
EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
478
479
/**
480
* cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
481
* (non-protocol) with HW-generated initialization
482
* vector.
483
* @desc: pointer to buffer used for descriptor construction
484
* @cdata: pointer to block cipher transform definitions
485
* Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
486
* with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
487
* @adata: pointer to authentication transform definitions.
488
* A split key is required for SEC Era < 6; the size of the split key
489
* is specified in this case. Valid algorithm values - one of
490
* OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
491
* with OP_ALG_AAI_HMAC_PRECOMP.
492
* @ivsize: initialization vector size
493
* @icvsize: integrity check value (ICV) size (truncated or full)
494
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
495
* @nonce: pointer to rfc3686 nonce
496
* @ctx1_iv_off: IV offset in CONTEXT1 register
497
* @is_qi: true when called from caam/qi
498
* @era: SEC Era
499
*/
500
void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
501
struct alginfo *adata, unsigned int ivsize,
502
unsigned int icvsize, const bool is_rfc3686,
503
u32 *nonce, const u32 ctx1_iv_off,
504
const bool is_qi, int era)
505
{
506
u32 geniv, moveiv;
507
u32 *wait_cmd;
508
509
/* Note: Context registers are saved. */
510
init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
511
512
if (is_qi) {
513
u32 *wait_load_cmd;
514
515
/* REG3 = assoclen */
516
append_seq_load(desc, 4, LDST_CLASS_DECO |
517
LDST_SRCDST_WORD_DECO_MATH3 |
518
(4 << LDST_OFFSET_SHIFT));
519
520
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
521
JUMP_COND_CALM | JUMP_COND_NCP |
522
JUMP_COND_NOP | JUMP_COND_NIP |
523
JUMP_COND_NIFP);
524
set_jump_tgt_here(desc, wait_load_cmd);
525
}
526
527
if (is_rfc3686) {
528
if (is_qi)
529
append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
530
LDST_SRCDST_BYTE_CONTEXT |
531
(ctx1_iv_off << LDST_OFFSET_SHIFT));
532
533
goto copy_iv;
534
}
535
536
/* Generate IV */
537
geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
538
NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
539
NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
540
append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
541
LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
542
append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
543
append_move(desc, MOVE_WAITCOMP |
544
MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
545
(ctx1_iv_off << MOVE_OFFSET_SHIFT) |
546
(ivsize << MOVE_LEN_SHIFT));
547
append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
548
549
copy_iv:
550
/* Copy IV to class 1 context */
551
append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
552
(ctx1_iv_off << MOVE_OFFSET_SHIFT) |
553
(ivsize << MOVE_LEN_SHIFT));
554
555
/* Return to encryption */
556
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
557
OP_ALG_ENCRYPT);
558
559
/* Read and write assoclen bytes */
560
if (is_qi || era < 3) {
561
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
562
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
563
} else {
564
append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
565
append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
566
}
567
568
/* Skip assoc data */
569
append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
570
571
/* read assoc before reading payload */
572
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
573
KEY_VLF);
574
575
/* Copy iv from outfifo to class 2 fifo */
576
moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
577
NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
578
append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
579
LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
580
append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
581
LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
582
583
/* Load Counter into CONTEXT1 reg */
584
if (is_rfc3686)
585
append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
586
LDST_SRCDST_BYTE_CONTEXT |
587
((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
588
LDST_OFFSET_SHIFT));
589
590
/* Class 1 operation */
591
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
592
OP_ALG_ENCRYPT);
593
594
/* Will write ivsize + cryptlen */
595
append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
596
597
/* Not need to reload iv */
598
append_seq_fifo_load(desc, ivsize,
599
FIFOLD_CLASS_SKIP);
600
601
/* Will read cryptlen */
602
append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
603
604
/*
605
* Wait for IV transfer (ofifo -> class2) to finish before starting
606
* ciphertext transfer (ofifo -> external memory).
607
*/
608
wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NIFP);
609
set_jump_tgt_here(desc, wait_cmd);
610
611
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
612
FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
613
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
614
615
/* Write ICV */
616
append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
617
LDST_SRCDST_BYTE_CONTEXT);
618
619
print_hex_dump_debug("aead givenc shdesc@" __stringify(__LINE__)": ",
620
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
621
1);
622
}
623
EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
624
625
/**
626
* cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
627
* @desc: pointer to buffer used for descriptor construction
628
* @cdata: pointer to block cipher transform definitions
629
* Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
630
* @ivsize: initialization vector size
631
* @icvsize: integrity check value (ICV) size (truncated or full)
632
* @is_qi: true when called from caam/qi
633
*/
634
void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
635
unsigned int ivsize, unsigned int icvsize,
636
const bool is_qi)
637
{
638
u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
639
*zero_assoc_jump_cmd2;
640
641
init_sh_desc(desc, HDR_SHARE_SERIAL);
642
643
/* skip key loading if they are loaded due to sharing */
644
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
645
JUMP_COND_SHRD);
646
if (cdata->key_inline)
647
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
648
cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
649
else
650
append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
651
KEY_DEST_CLASS_REG);
652
set_jump_tgt_here(desc, key_jump_cmd);
653
654
/* class 1 operation */
655
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
656
OP_ALG_ENCRYPT);
657
658
if (is_qi) {
659
u32 *wait_load_cmd;
660
661
/* REG3 = assoclen */
662
append_seq_load(desc, 4, LDST_CLASS_DECO |
663
LDST_SRCDST_WORD_DECO_MATH3 |
664
(4 << LDST_OFFSET_SHIFT));
665
666
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
667
JUMP_COND_CALM | JUMP_COND_NCP |
668
JUMP_COND_NOP | JUMP_COND_NIP |
669
JUMP_COND_NIFP);
670
set_jump_tgt_here(desc, wait_load_cmd);
671
672
append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
673
ivsize);
674
} else {
675
append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
676
CAAM_CMD_SZ);
677
}
678
679
/* if assoclen + cryptlen is ZERO, skip to ICV write */
680
zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
681
JUMP_COND_MATH_Z);
682
683
if (is_qi)
684
append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
685
FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
686
687
/* if assoclen is ZERO, skip reading the assoc data */
688
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
689
zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
690
JUMP_COND_MATH_Z);
691
692
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
693
694
/* skip assoc data */
695
append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
696
697
/* cryptlen = seqinlen - assoclen */
698
append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
699
700
/* if cryptlen is ZERO jump to zero-payload commands */
701
zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
702
JUMP_COND_MATH_Z);
703
704
/* read assoc data */
705
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
706
FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
707
set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
708
709
append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
710
711
/* write encrypted data */
712
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
713
714
/* read payload data */
715
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
716
FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
717
718
/* jump to ICV writing */
719
if (is_qi)
720
append_jump(desc, JUMP_TEST_ALL | 4);
721
else
722
append_jump(desc, JUMP_TEST_ALL | 2);
723
724
/* zero-payload commands */
725
set_jump_tgt_here(desc, zero_payload_jump_cmd);
726
727
/* read assoc data */
728
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
729
FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
730
if (is_qi)
731
/* jump to ICV writing */
732
append_jump(desc, JUMP_TEST_ALL | 2);
733
734
/* There is no input data */
735
set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
736
737
if (is_qi)
738
append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
739
FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
740
FIFOLD_TYPE_LAST1);
741
742
/* write ICV */
743
append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
744
LDST_SRCDST_BYTE_CONTEXT);
745
746
print_hex_dump_debug("gcm enc shdesc@" __stringify(__LINE__)": ",
747
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
748
1);
749
}
750
EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
751
752
/**
753
* cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
754
* @desc: pointer to buffer used for descriptor construction
755
* @cdata: pointer to block cipher transform definitions
756
* Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
757
* @ivsize: initialization vector size
758
* @icvsize: integrity check value (ICV) size (truncated or full)
759
* @is_qi: true when called from caam/qi
760
*/
761
void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
762
unsigned int ivsize, unsigned int icvsize,
763
const bool is_qi)
764
{
765
u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
766
767
init_sh_desc(desc, HDR_SHARE_SERIAL);
768
769
/* skip key loading if they are loaded due to sharing */
770
key_jump_cmd = append_jump(desc, JUMP_JSL |
771
JUMP_TEST_ALL | JUMP_COND_SHRD);
772
if (cdata->key_inline)
773
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
774
cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
775
else
776
append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
777
KEY_DEST_CLASS_REG);
778
set_jump_tgt_here(desc, key_jump_cmd);
779
780
/* class 1 operation */
781
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
782
OP_ALG_DECRYPT | OP_ALG_ICV_ON);
783
784
if (is_qi) {
785
u32 *wait_load_cmd;
786
787
/* REG3 = assoclen */
788
append_seq_load(desc, 4, LDST_CLASS_DECO |
789
LDST_SRCDST_WORD_DECO_MATH3 |
790
(4 << LDST_OFFSET_SHIFT));
791
792
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
793
JUMP_COND_CALM | JUMP_COND_NCP |
794
JUMP_COND_NOP | JUMP_COND_NIP |
795
JUMP_COND_NIFP);
796
set_jump_tgt_here(desc, wait_load_cmd);
797
798
append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
799
FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
800
}
801
802
/* if assoclen is ZERO, skip reading the assoc data */
803
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
804
zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
805
JUMP_COND_MATH_Z);
806
807
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
808
809
/* skip assoc data */
810
append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
811
812
/* read assoc data */
813
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
814
FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
815
816
set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
817
818
/* cryptlen = seqoutlen - assoclen */
819
append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
820
821
/* jump to zero-payload command if cryptlen is zero */
822
zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
823
JUMP_COND_MATH_Z);
824
825
append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
826
827
/* store encrypted data */
828
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
829
830
/* read payload data */
831
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
832
FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
833
834
/* zero-payload command */
835
set_jump_tgt_here(desc, zero_payload_jump_cmd);
836
837
/* read ICV */
838
append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
839
FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
840
841
print_hex_dump_debug("gcm dec shdesc@" __stringify(__LINE__)": ",
842
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
843
1);
844
}
845
EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
846
847
/**
848
* cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
849
* (non-protocol).
850
* @desc: pointer to buffer used for descriptor construction
851
* @cdata: pointer to block cipher transform definitions
852
* Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
853
* @ivsize: initialization vector size
854
* @icvsize: integrity check value (ICV) size (truncated or full)
855
* @is_qi: true when called from caam/qi
856
*
857
* Input sequence: AAD | PTXT
858
* Output sequence: AAD | CTXT | ICV
859
* AAD length (assoclen), which includes the IV length, is available in Math3.
860
*/
861
void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
862
unsigned int ivsize, unsigned int icvsize,
863
const bool is_qi)
864
{
865
u32 *key_jump_cmd, *zero_cryptlen_jump_cmd, *skip_instructions;
866
init_sh_desc(desc, HDR_SHARE_SERIAL);
867
868
/* Skip key loading if it is loaded due to sharing */
869
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
870
JUMP_COND_SHRD);
871
if (cdata->key_inline)
872
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
873
cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
874
else
875
append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
876
KEY_DEST_CLASS_REG);
877
set_jump_tgt_here(desc, key_jump_cmd);
878
879
/* Class 1 operation */
880
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
881
OP_ALG_ENCRYPT);
882
883
if (is_qi) {
884
u32 *wait_load_cmd;
885
886
/* REG3 = assoclen */
887
append_seq_load(desc, 4, LDST_CLASS_DECO |
888
LDST_SRCDST_WORD_DECO_MATH3 |
889
(4 << LDST_OFFSET_SHIFT));
890
891
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
892
JUMP_COND_CALM | JUMP_COND_NCP |
893
JUMP_COND_NOP | JUMP_COND_NIP |
894
JUMP_COND_NIFP);
895
set_jump_tgt_here(desc, wait_load_cmd);
896
897
/* Read salt and IV */
898
append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
899
cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
900
FIFOLD_TYPE_IV);
901
append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
902
FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
903
}
904
905
append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
906
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
907
908
/* Skip AAD */
909
append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
910
911
/* Read cryptlen and set this value into VARSEQOUTLEN */
912
append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
913
914
/* If cryptlen is ZERO jump to AAD command */
915
zero_cryptlen_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
916
JUMP_COND_MATH_Z);
917
918
/* Read AAD data */
919
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
920
FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
921
922
/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
923
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA);
924
925
/* Skip IV */
926
append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
927
append_math_add(desc, VARSEQINLEN, VARSEQOUTLEN, REG0, CAAM_CMD_SZ);
928
929
/* Write encrypted data */
930
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
931
932
/* Read payload data */
933
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
934
FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
935
936
/* Jump instructions to avoid double reading of AAD */
937
skip_instructions = append_jump(desc, JUMP_TEST_ALL);
938
939
/* There is no input data, cryptlen = 0 */
940
set_jump_tgt_here(desc, zero_cryptlen_jump_cmd);
941
942
/* Read AAD */
943
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
944
FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
945
946
set_jump_tgt_here(desc, skip_instructions);
947
948
/* Write ICV */
949
append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
950
LDST_SRCDST_BYTE_CONTEXT);
951
952
print_hex_dump_debug("rfc4106 enc shdesc@" __stringify(__LINE__)": ",
953
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
954
1);
955
}
956
EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
957
958
/**
959
* cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
960
* (non-protocol).
961
* @desc: pointer to buffer used for descriptor construction
962
* @cdata: pointer to block cipher transform definitions
963
* Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
964
* @ivsize: initialization vector size
965
* @icvsize: integrity check value (ICV) size (truncated or full)
966
* @is_qi: true when called from caam/qi
967
*/
968
void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
969
unsigned int ivsize, unsigned int icvsize,
970
const bool is_qi)
971
{
972
u32 *key_jump_cmd;
973
974
init_sh_desc(desc, HDR_SHARE_SERIAL);
975
976
/* Skip key loading if it is loaded due to sharing */
977
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
978
JUMP_COND_SHRD);
979
if (cdata->key_inline)
980
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
981
cdata->keylen, CLASS_1 |
982
KEY_DEST_CLASS_REG);
983
else
984
append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
985
KEY_DEST_CLASS_REG);
986
set_jump_tgt_here(desc, key_jump_cmd);
987
988
/* Class 1 operation */
989
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
990
OP_ALG_DECRYPT | OP_ALG_ICV_ON);
991
992
if (is_qi) {
993
u32 *wait_load_cmd;
994
995
/* REG3 = assoclen */
996
append_seq_load(desc, 4, LDST_CLASS_DECO |
997
LDST_SRCDST_WORD_DECO_MATH3 |
998
(4 << LDST_OFFSET_SHIFT));
999
1000
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1001
JUMP_COND_CALM | JUMP_COND_NCP |
1002
JUMP_COND_NOP | JUMP_COND_NIP |
1003
JUMP_COND_NIFP);
1004
set_jump_tgt_here(desc, wait_load_cmd);
1005
1006
/* Read salt and IV */
1007
append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1008
cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1009
FIFOLD_TYPE_IV);
1010
append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1011
FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1012
}
1013
1014
append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
1015
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1016
1017
/* Read assoc data */
1018
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1019
FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
1020
1021
/* Skip IV */
1022
append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
1023
1024
/* Will read cryptlen bytes */
1025
append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
1026
1027
/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
1028
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
1029
1030
/* Skip assoc data */
1031
append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
1032
1033
/* Will write cryptlen bytes */
1034
append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1035
1036
/* Store payload data */
1037
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1038
1039
/* Read encrypted data */
1040
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1041
FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
1042
1043
/* Read ICV */
1044
append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1045
FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1046
1047
print_hex_dump_debug("rfc4106 dec shdesc@" __stringify(__LINE__)": ",
1048
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1049
1);
1050
}
1051
EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
1052
1053
/**
1054
* cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
1055
* (non-protocol).
1056
* @desc: pointer to buffer used for descriptor construction
1057
* @cdata: pointer to block cipher transform definitions
1058
* Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1059
* @ivsize: initialization vector size
1060
* @icvsize: integrity check value (ICV) size (truncated or full)
1061
* @is_qi: true when called from caam/qi
1062
*/
1063
void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
1064
unsigned int ivsize, unsigned int icvsize,
1065
const bool is_qi)
1066
{
1067
u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1068
1069
init_sh_desc(desc, HDR_SHARE_SERIAL);
1070
1071
/* Skip key loading if it is loaded due to sharing */
1072
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1073
JUMP_COND_SHRD);
1074
if (cdata->key_inline)
1075
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1076
cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1077
else
1078
append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1079
KEY_DEST_CLASS_REG);
1080
set_jump_tgt_here(desc, key_jump_cmd);
1081
1082
/* Class 1 operation */
1083
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1084
OP_ALG_ENCRYPT);
1085
1086
if (is_qi) {
1087
/* assoclen is not needed, skip it */
1088
append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1089
1090
/* Read salt and IV */
1091
append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1092
cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1093
FIFOLD_TYPE_IV);
1094
append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1095
FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1096
}
1097
1098
/* assoclen + cryptlen = seqinlen */
1099
append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
1100
1101
/*
1102
* MOVE_LEN opcode is not available in all SEC HW revisions,
1103
* thus need to do some magic, i.e. self-patch the descriptor
1104
* buffer.
1105
*/
1106
read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1107
(0x6 << MOVE_LEN_SHIFT));
1108
write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1109
(0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1110
1111
/* Will read assoclen + cryptlen bytes */
1112
append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1113
1114
/* Will write assoclen + cryptlen bytes */
1115
append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1116
1117
/* Read and write assoclen + cryptlen bytes */
1118
aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
1119
1120
set_move_tgt_here(desc, read_move_cmd);
1121
set_move_tgt_here(desc, write_move_cmd);
1122
append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1123
/* Move payload data to OFIFO */
1124
append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1125
1126
/* Write ICV */
1127
append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
1128
LDST_SRCDST_BYTE_CONTEXT);
1129
1130
print_hex_dump_debug("rfc4543 enc shdesc@" __stringify(__LINE__)": ",
1131
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1132
1);
1133
}
1134
EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
1135
1136
/**
1137
* cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
1138
* (non-protocol).
1139
* @desc: pointer to buffer used for descriptor construction
1140
* @cdata: pointer to block cipher transform definitions
1141
* Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1142
* @ivsize: initialization vector size
1143
* @icvsize: integrity check value (ICV) size (truncated or full)
1144
* @is_qi: true when called from caam/qi
1145
*/
1146
void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
1147
unsigned int ivsize, unsigned int icvsize,
1148
const bool is_qi)
1149
{
1150
u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1151
1152
init_sh_desc(desc, HDR_SHARE_SERIAL);
1153
1154
/* Skip key loading if it is loaded due to sharing */
1155
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1156
JUMP_COND_SHRD);
1157
if (cdata->key_inline)
1158
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1159
cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1160
else
1161
append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1162
KEY_DEST_CLASS_REG);
1163
set_jump_tgt_here(desc, key_jump_cmd);
1164
1165
/* Class 1 operation */
1166
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1167
OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1168
1169
if (is_qi) {
1170
/* assoclen is not needed, skip it */
1171
append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1172
1173
/* Read salt and IV */
1174
append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1175
cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1176
FIFOLD_TYPE_IV);
1177
append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1178
FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1179
}
1180
1181
/* assoclen + cryptlen = seqoutlen */
1182
append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1183
1184
/*
1185
* MOVE_LEN opcode is not available in all SEC HW revisions,
1186
* thus need to do some magic, i.e. self-patch the descriptor
1187
* buffer.
1188
*/
1189
read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1190
(0x6 << MOVE_LEN_SHIFT));
1191
write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1192
(0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1193
1194
/* Will read assoclen + cryptlen bytes */
1195
append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1196
1197
/* Will write assoclen + cryptlen bytes */
1198
append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1199
1200
/* Store payload data */
1201
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1202
1203
/* In-snoop assoclen + cryptlen data */
1204
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
1205
FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
1206
1207
set_move_tgt_here(desc, read_move_cmd);
1208
set_move_tgt_here(desc, write_move_cmd);
1209
append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1210
/* Move payload data to OFIFO */
1211
append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1212
append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
1213
1214
/* Read ICV */
1215
append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1216
FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1217
1218
print_hex_dump_debug("rfc4543 dec shdesc@" __stringify(__LINE__)": ",
1219
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1220
1);
1221
}
1222
EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
1223
1224
/**
1225
* cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and
1226
* IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared
1227
* descriptor (non-protocol).
1228
* @desc: pointer to buffer used for descriptor construction
1229
* @cdata: pointer to block cipher transform definitions
1230
* Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with
1231
* OP_ALG_AAI_AEAD.
1232
* @adata: pointer to authentication transform definitions
1233
* Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with
1234
* OP_ALG_AAI_AEAD.
1235
* @ivsize: initialization vector size
1236
* @icvsize: integrity check value (ICV) size (truncated or full)
1237
* @encap: true if encapsulation, false if decapsulation
1238
* @is_qi: true when called from caam/qi
1239
*/
1240
void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
1241
struct alginfo *adata, unsigned int ivsize,
1242
unsigned int icvsize, const bool encap,
1243
const bool is_qi)
1244
{
1245
u32 *key_jump_cmd, *wait_cmd;
1246
u32 nfifo;
1247
const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE);
1248
1249
/* Note: Context registers are saved. */
1250
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1251
1252
/* skip key loading if they are loaded due to sharing */
1253
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1254
JUMP_COND_SHRD);
1255
1256
append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen,
1257
CLASS_1 | KEY_DEST_CLASS_REG);
1258
1259
/* For IPsec load the salt from keymat in the context register */
1260
if (is_ipsec)
1261
append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4,
1262
LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT |
1263
4 << LDST_OFFSET_SHIFT);
1264
1265
set_jump_tgt_here(desc, key_jump_cmd);
1266
1267
/* Class 2 and 1 operations: Poly & ChaCha */
1268
if (encap) {
1269
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1270
OP_ALG_ENCRYPT);
1271
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1272
OP_ALG_ENCRYPT);
1273
} else {
1274
append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1275
OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1276
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1277
OP_ALG_DECRYPT);
1278
}
1279
1280
if (is_qi) {
1281
u32 *wait_load_cmd;
1282
u32 ctx1_iv_off = is_ipsec ? 8 : 4;
1283
1284
/* REG3 = assoclen */
1285
append_seq_load(desc, 4, LDST_CLASS_DECO |
1286
LDST_SRCDST_WORD_DECO_MATH3 |
1287
4 << LDST_OFFSET_SHIFT);
1288
1289
wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1290
JUMP_COND_CALM | JUMP_COND_NCP |
1291
JUMP_COND_NOP | JUMP_COND_NIP |
1292
JUMP_COND_NIFP);
1293
set_jump_tgt_here(desc, wait_load_cmd);
1294
1295
append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
1296
LDST_SRCDST_BYTE_CONTEXT |
1297
ctx1_iv_off << LDST_OFFSET_SHIFT);
1298
}
1299
1300
/*
1301
* MAGIC with NFIFO
1302
* Read associated data from the input and send them to class1 and
1303
* class2 alignment blocks. From class1 send data to output fifo and
1304
* then write it to memory since we don't need to encrypt AD.
1305
*/
1306
nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 |
1307
NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND;
1308
append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB |
1309
LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3);
1310
1311
append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
1312
append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1313
append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO |
1314
FIFOLD_CLASS_CLASS1 | LDST_VLF);
1315
append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK |
1316
MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3);
1317
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
1318
1319
/* IPsec - copy IV at the output */
1320
if (is_ipsec)
1321
append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA |
1322
0x2 << 25);
1323
1324
wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
1325
JUMP_COND_NOP | JUMP_TEST_ALL);
1326
set_jump_tgt_here(desc, wait_cmd);
1327
1328
if (encap) {
1329
/* Read and write cryptlen bytes */
1330
append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1331
append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0,
1332
CAAM_CMD_SZ);
1333
aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
1334
1335
/* Write ICV */
1336
append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
1337
LDST_SRCDST_BYTE_CONTEXT);
1338
} else {
1339
/* Read and write cryptlen bytes */
1340
append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0,
1341
CAAM_CMD_SZ);
1342
append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0,
1343
CAAM_CMD_SZ);
1344
aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
1345
1346
/* Load ICV for verification */
1347
append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
1348
FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
1349
}
1350
1351
print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ",
1352
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1353
1);
1354
}
1355
EXPORT_SYMBOL(cnstr_shdsc_chachapoly);
1356
1357
/* For skcipher encrypt and decrypt, read from req->src and write to req->dst */
1358
static inline void skcipher_append_src_dst(u32 *desc)
1359
{
1360
append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1361
append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1362
append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
1363
KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
1364
append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
1365
}
1366
1367
/**
1368
* cnstr_shdsc_skcipher_encap - skcipher encapsulation shared descriptor
1369
* @desc: pointer to buffer used for descriptor construction
1370
* @cdata: pointer to block cipher transform definitions
1371
* Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1372
* with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1373
* - OP_ALG_ALGSEL_CHACHA20
1374
* @ivsize: initialization vector size
1375
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1376
* @ctx1_iv_off: IV offset in CONTEXT1 register
1377
*/
1378
void cnstr_shdsc_skcipher_encap(u32 * const desc, struct alginfo *cdata,
1379
unsigned int ivsize, const bool is_rfc3686,
1380
const u32 ctx1_iv_off)
1381
{
1382
u32 *key_jump_cmd;
1383
u32 options = cdata->algtype | OP_ALG_AS_INIT | OP_ALG_ENCRYPT;
1384
bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
1385
OP_ALG_ALGSEL_CHACHA20);
1386
1387
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1388
/* Skip if already shared */
1389
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1390
JUMP_COND_SHRD);
1391
1392
/* Load class1 key only */
1393
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1394
cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1395
1396
/* Load nonce into CONTEXT1 reg */
1397
if (is_rfc3686) {
1398
const u8 *nonce = cdata->key_virt + cdata->keylen;
1399
1400
append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1401
LDST_CLASS_IND_CCB |
1402
LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1403
append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1404
MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1405
(CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1406
}
1407
1408
set_jump_tgt_here(desc, key_jump_cmd);
1409
1410
/* Load IV, if there is one */
1411
if (ivsize)
1412
append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1413
LDST_CLASS_1_CCB | (ctx1_iv_off <<
1414
LDST_OFFSET_SHIFT));
1415
1416
/* Load counter into CONTEXT1 reg */
1417
if (is_rfc3686)
1418
append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1419
LDST_SRCDST_BYTE_CONTEXT |
1420
((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1421
LDST_OFFSET_SHIFT));
1422
1423
/* Load operation */
1424
if (is_chacha20)
1425
options |= OP_ALG_AS_FINALIZE;
1426
append_operation(desc, options);
1427
1428
/* Perform operation */
1429
skcipher_append_src_dst(desc);
1430
1431
/* Store IV */
1432
if (!is_chacha20 && ivsize)
1433
append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1434
LDST_CLASS_1_CCB | (ctx1_iv_off <<
1435
LDST_OFFSET_SHIFT));
1436
1437
print_hex_dump_debug("skcipher enc shdesc@" __stringify(__LINE__)": ",
1438
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1439
1);
1440
}
1441
EXPORT_SYMBOL(cnstr_shdsc_skcipher_encap);
1442
1443
/**
1444
* cnstr_shdsc_skcipher_decap - skcipher decapsulation shared descriptor
1445
* @desc: pointer to buffer used for descriptor construction
1446
* @cdata: pointer to block cipher transform definitions
1447
* Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1448
* with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1449
* - OP_ALG_ALGSEL_CHACHA20
1450
* @ivsize: initialization vector size
1451
* @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1452
* @ctx1_iv_off: IV offset in CONTEXT1 register
1453
*/
1454
void cnstr_shdsc_skcipher_decap(u32 * const desc, struct alginfo *cdata,
1455
unsigned int ivsize, const bool is_rfc3686,
1456
const u32 ctx1_iv_off)
1457
{
1458
u32 *key_jump_cmd;
1459
bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
1460
OP_ALG_ALGSEL_CHACHA20);
1461
1462
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1463
/* Skip if already shared */
1464
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1465
JUMP_COND_SHRD);
1466
1467
/* Load class1 key only */
1468
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1469
cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1470
1471
/* Load nonce into CONTEXT1 reg */
1472
if (is_rfc3686) {
1473
const u8 *nonce = cdata->key_virt + cdata->keylen;
1474
1475
append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1476
LDST_CLASS_IND_CCB |
1477
LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1478
append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1479
MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1480
(CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1481
}
1482
1483
set_jump_tgt_here(desc, key_jump_cmd);
1484
1485
/* Load IV, if there is one */
1486
if (ivsize)
1487
append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1488
LDST_CLASS_1_CCB | (ctx1_iv_off <<
1489
LDST_OFFSET_SHIFT));
1490
1491
/* Load counter into CONTEXT1 reg */
1492
if (is_rfc3686)
1493
append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1494
LDST_SRCDST_BYTE_CONTEXT |
1495
((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1496
LDST_OFFSET_SHIFT));
1497
1498
/* Choose operation */
1499
if (ctx1_iv_off)
1500
append_operation(desc, cdata->algtype | OP_ALG_AS_INIT |
1501
OP_ALG_DECRYPT);
1502
else
1503
append_dec_op1(desc, cdata->algtype);
1504
1505
/* Perform operation */
1506
skcipher_append_src_dst(desc);
1507
1508
/* Store IV */
1509
if (!is_chacha20 && ivsize)
1510
append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1511
LDST_CLASS_1_CCB | (ctx1_iv_off <<
1512
LDST_OFFSET_SHIFT));
1513
1514
print_hex_dump_debug("skcipher dec shdesc@" __stringify(__LINE__)": ",
1515
DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1516
1);
1517
}
1518
EXPORT_SYMBOL(cnstr_shdsc_skcipher_decap);
1519
1520
/**
1521
* cnstr_shdsc_xts_skcipher_encap - xts skcipher encapsulation shared descriptor
1522
* @desc: pointer to buffer used for descriptor construction
1523
* @cdata: pointer to block cipher transform definitions
1524
* Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1525
*/
1526
void cnstr_shdsc_xts_skcipher_encap(u32 * const desc, struct alginfo *cdata)
1527
{
1528
/*
1529
* Set sector size to a big value, practically disabling
1530
* sector size segmentation in xts implementation. We cannot
1531
* take full advantage of this HW feature with existing
1532
* crypto API / dm-crypt SW architecture.
1533
*/
1534
__be64 sector_size = cpu_to_be64(BIT(15));
1535
u32 *key_jump_cmd;
1536
1537
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1538
/* Skip if already shared */
1539
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1540
JUMP_COND_SHRD);
1541
1542
/* Load class1 keys only */
1543
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1544
cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1545
1546
/* Load sector size with index 40 bytes (0x28) */
1547
append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
1548
LDST_SRCDST_BYTE_CONTEXT |
1549
(0x28 << LDST_OFFSET_SHIFT));
1550
1551
set_jump_tgt_here(desc, key_jump_cmd);
1552
1553
/*
1554
* create sequence for loading the sector index / 16B tweak value
1555
* Lower 8B of IV - sector index / tweak lower half
1556
* Upper 8B of IV - upper half of 16B tweak
1557
*/
1558
append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1559
(0x20 << LDST_OFFSET_SHIFT));
1560
append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1561
(0x30 << LDST_OFFSET_SHIFT));
1562
1563
/* Load operation */
1564
append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1565
OP_ALG_ENCRYPT);
1566
1567
/* Perform operation */
1568
skcipher_append_src_dst(desc);
1569
1570
/* Store lower 8B and upper 8B of IV */
1571
append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1572
(0x20 << LDST_OFFSET_SHIFT));
1573
append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1574
(0x30 << LDST_OFFSET_SHIFT));
1575
1576
print_hex_dump_debug("xts skcipher enc shdesc@" __stringify(__LINE__)
1577
": ", DUMP_PREFIX_ADDRESS, 16, 4,
1578
desc, desc_bytes(desc), 1);
1579
}
1580
EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_encap);
1581
1582
/**
1583
* cnstr_shdsc_xts_skcipher_decap - xts skcipher decapsulation shared descriptor
1584
* @desc: pointer to buffer used for descriptor construction
1585
* @cdata: pointer to block cipher transform definitions
1586
* Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1587
*/
1588
void cnstr_shdsc_xts_skcipher_decap(u32 * const desc, struct alginfo *cdata)
1589
{
1590
/*
1591
* Set sector size to a big value, practically disabling
1592
* sector size segmentation in xts implementation. We cannot
1593
* take full advantage of this HW feature with existing
1594
* crypto API / dm-crypt SW architecture.
1595
*/
1596
__be64 sector_size = cpu_to_be64(BIT(15));
1597
u32 *key_jump_cmd;
1598
1599
init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1600
/* Skip if already shared */
1601
key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1602
JUMP_COND_SHRD);
1603
1604
/* Load class1 key only */
1605
append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1606
cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1607
1608
/* Load sector size with index 40 bytes (0x28) */
1609
append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
1610
LDST_SRCDST_BYTE_CONTEXT |
1611
(0x28 << LDST_OFFSET_SHIFT));
1612
1613
set_jump_tgt_here(desc, key_jump_cmd);
1614
1615
/*
1616
* create sequence for loading the sector index / 16B tweak value
1617
* Lower 8B of IV - sector index / tweak lower half
1618
* Upper 8B of IV - upper half of 16B tweak
1619
*/
1620
append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1621
(0x20 << LDST_OFFSET_SHIFT));
1622
append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1623
(0x30 << LDST_OFFSET_SHIFT));
1624
/* Load operation */
1625
append_dec_op1(desc, cdata->algtype);
1626
1627
/* Perform operation */
1628
skcipher_append_src_dst(desc);
1629
1630
/* Store lower 8B and upper 8B of IV */
1631
append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1632
(0x20 << LDST_OFFSET_SHIFT));
1633
append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1634
(0x30 << LDST_OFFSET_SHIFT));
1635
1636
print_hex_dump_debug("xts skcipher dec shdesc@" __stringify(__LINE__)
1637
": ", DUMP_PREFIX_ADDRESS, 16, 4, desc,
1638
desc_bytes(desc), 1);
1639
}
1640
EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_decap);
1641
1642
MODULE_LICENSE("GPL");
1643
MODULE_DESCRIPTION("FSL CAAM descriptor support");
1644
MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
1645
1646