crypto/dpaa2_sec/hw: support SNOW-f8
[dpdk.git] / drivers / crypto / dpaa2_sec / hw / desc / algo.h
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2008-2016 Freescale Semiconductor Inc.
4  * Copyright 2016,2019 NXP
5  *
6  */
7
8 #ifndef __DESC_ALGO_H__
9 #define __DESC_ALGO_H__
10
11 #include "hw/rta.h"
12 #include "common.h"
13
14 /**
15  * DOC: Algorithms - Shared Descriptor Constructors
16  *
17  * Shared descriptors for algorithms (i.e. not for protocols).
18  */
19
20 /**
21  * cnstr_shdsc_snow_f8 - SNOW/f8 (UEA2) as a shared descriptor
22  * @descbuf: pointer to descriptor-under-construction buffer
23  * @ps: if 36/40bit addressing is desired, this parameter must be true
24  * @swap: must be true when core endianness doesn't match SEC endianness
25  * @cipherdata: pointer to block cipher transform definitions
26  * @dir: Cipher direction (DIR_ENC/DIR_DEC)
27  *
28  * Return: size of descriptor written in words or negative number on error
29  */
30 static inline int
31 cnstr_shdsc_snow_f8(uint32_t *descbuf, bool ps, bool swap,
32                     struct alginfo *cipherdata, uint8_t dir)
33 {
34         struct program prg;
35         struct program *p = &prg;
36
37         PROGRAM_CNTXT_INIT(p, descbuf, 0);
38         if (swap)
39                 PROGRAM_SET_BSWAP(p);
40
41         if (ps)
42                 PROGRAM_SET_36BIT_ADDR(p);
43         SHR_HDR(p, SHR_ALWAYS, 1, 0);
44
45         KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
46             cipherdata->keylen, INLINE_KEY(cipherdata));
47
48         SEQLOAD(p, CONTEXT1, 0, 16, 0);
49
50         MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
51         MATHB(p, SEQINSZ, SUB, MATH2, VSEQOUTSZ, 4, 0);
52         ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8,
53                       OP_ALG_AS_INITFINAL, 0, dir);
54         SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1);
55         SEQFIFOSTORE(p, MSG, 0, 0, VLF);
56
57         return PROGRAM_FINALIZE(p);
58 }
59
60 /**
61  * cnstr_shdsc_snow_f9 - SNOW/f9 (UIA2) as a shared descriptor
62  * @descbuf: pointer to descriptor-under-construction buffer
63  * @ps: if 36/40bit addressing is desired, this parameter must be true
64  * @swap: must be true when core endianness doesn't match SEC endianness
65  * @authdata: pointer to authentication transform definitions
66  * @dir: cipher direction (DIR_ENC/DIR_DEC)
67  * @count: UEA2 count value (32 bits)
68  * @fresh: UEA2 fresh value ID (32 bits)
69  * @direction: UEA2 direction (1 bit)
70  * @datalen: size of data
71  *
72  * Return: size of descriptor written in words or negative number on error
73  */
74 static inline int
75 cnstr_shdsc_snow_f9(uint32_t *descbuf, bool ps, bool swap,
76                     struct alginfo *authdata, uint8_t dir, uint32_t count,
77                     uint32_t fresh, uint8_t direction, uint32_t datalen)
78 {
79         struct program prg;
80         struct program *p = &prg;
81         uint64_t ct = count;
82         uint64_t fr = fresh;
83         uint64_t dr = direction;
84         uint64_t context[2];
85
86         context[0] = (ct << 32) | (dr << 26);
87         context[1] = fr << 32;
88
89         PROGRAM_CNTXT_INIT(p, descbuf, 0);
90         if (swap) {
91                 PROGRAM_SET_BSWAP(p);
92
93                 context[0] = swab64(context[0]);
94                 context[1] = swab64(context[1]);
95         }
96         if (ps)
97                 PROGRAM_SET_36BIT_ADDR(p);
98         SHR_HDR(p, SHR_ALWAYS, 1, 0);
99
100         KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
101             INLINE_KEY(authdata));
102         MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
103         ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9, OP_ALG_AAI_F9,
104                       OP_ALG_AS_INITFINAL, 0, dir);
105         LOAD(p, (uintptr_t)context, CONTEXT2, 0, 16, IMMED | COPY);
106         SEQFIFOLOAD(p, BIT_DATA, datalen, CLASS2 | LAST2);
107         /* Save lower half of MAC out into a 32-bit sequence */
108         SEQSTORE(p, CONTEXT2, 0, 4, 0);
109
110         return PROGRAM_FINALIZE(p);
111 }
112
113 /**
114  * cnstr_shdsc_blkcipher - block cipher transformation
115  * @descbuf: pointer to descriptor-under-construction buffer
116  * @ps: if 36/40bit addressing is desired, this parameter must be true
117  * @swap: must be true when core endianness doesn't match SEC endianness
118  * @share: sharing type of shared descriptor
119  * @cipherdata: pointer to block cipher transform definitions
120  *              Valid algorithm values one of OP_ALG_ALGSEL_* {DES, 3DES, AES}
121  *              Valid modes for:
122  *                  AES: OP_ALG_AAI_* {CBC, CTR}
123  *                  DES, 3DES: OP_ALG_AAI_CBC
124  * @iv: IV data; if NULL, "ivlen" bytes from the input frame will be read as IV
125  * @ivlen: IV length
126  * @dir: DIR_ENC/DIR_DEC
127  *
128  * Return: size of descriptor written in words or negative number on error
129  */
130 static inline int
131 cnstr_shdsc_blkcipher(uint32_t *descbuf, bool ps, bool swap,
132                       enum rta_share_type share,
133                       struct alginfo *cipherdata, uint8_t *iv,
134                       uint32_t ivlen, uint8_t dir)
135 {
136         struct program prg;
137         struct program *p = &prg;
138         uint32_t iv_off = 0;
139         const bool need_dk = (dir == DIR_DEC) &&
140                              (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
141                              (cipherdata->algmode == OP_ALG_AAI_CBC);
142         LABEL(keyjmp);
143         LABEL(skipdk);
144         REFERENCE(pkeyjmp);
145         REFERENCE(pskipdk);
146
147         PROGRAM_CNTXT_INIT(p, descbuf, 0);
148         if (swap)
149                 PROGRAM_SET_BSWAP(p);
150         if (ps)
151                 PROGRAM_SET_36BIT_ADDR(p);
152         SHR_HDR(p, share, 1, SC);
153
154         pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
155         /* Insert Key */
156         KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
157             cipherdata->keylen, INLINE_KEY(cipherdata));
158
159         if (need_dk) {
160                 ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
161                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
162
163                 pskipdk = JUMP(p, skipdk, LOCAL_JUMP, ALL_TRUE, 0);
164         }
165         SET_LABEL(p, keyjmp);
166
167         if (need_dk) {
168                 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode |
169                               OP_ALG_AAI_DK, OP_ALG_AS_INITFINAL,
170                               ICV_CHECK_DISABLE, dir);
171                 SET_LABEL(p, skipdk);
172         } else {
173                 ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
174                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
175         }
176
177         if (cipherdata->algmode == OP_ALG_AAI_CTR)
178                 iv_off = 16;
179
180         if (iv)
181                 /* IV load, convert size */
182                 LOAD(p, (uintptr_t)iv, CONTEXT1, iv_off, ivlen, IMMED | COPY);
183         else
184                 /* IV is present first before the actual message */
185                 SEQLOAD(p, CONTEXT1, iv_off, ivlen, 0);
186
187         MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
188         MATHB(p, SEQINSZ, SUB, MATH2, VSEQOUTSZ, 4, 0);
189
190         /* Insert sequence load/store with VLF */
191         SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1);
192         SEQFIFOSTORE(p, MSG, 0, 0, VLF);
193
194         PATCH_JUMP(p, pkeyjmp, keyjmp);
195         if (need_dk)
196                 PATCH_JUMP(p, pskipdk, skipdk);
197
198         return PROGRAM_FINALIZE(p);
199 }
200
201 /**
202  * cnstr_shdsc_hmac - HMAC shared
203  * @descbuf: pointer to descriptor-under-construction buffer
204  * @ps: if 36/40bit addressing is desired, this parameter must be true
205  * @swap: must be true when core endianness doesn't match SEC endianness
206  * @share: sharing type of shared descriptor
207  * @authdata: pointer to authentication transform definitions;
208  *            message digest algorithm: OP_ALG_ALGSEL_MD5/ SHA1-512.
209  * @do_icv: 0 if ICV checking is not desired, any other value if ICV checking
210  *          is needed for all the packets processed by this shared descriptor
211  * @trunc_len: Length of the truncated ICV to be written in the output buffer, 0
212  *             if no truncation is needed
213  *
214  * Note: There's no support for keys longer than the block size of the
215  * underlying hash function, according to the selected algorithm.
216  *
217  * Return: size of descriptor written in words or negative number on error
218  */
219 static inline int
220 cnstr_shdsc_hmac(uint32_t *descbuf, bool ps, bool swap,
221                  enum rta_share_type share,
222                  struct alginfo *authdata, uint8_t do_icv,
223                  uint8_t trunc_len)
224 {
225         struct program prg;
226         struct program *p = &prg;
227         uint8_t storelen, opicv, dir;
228         LABEL(keyjmp);
229         LABEL(jmpprecomp);
230         REFERENCE(pkeyjmp);
231         REFERENCE(pjmpprecomp);
232
233         /* Compute fixed-size store based on alg selection */
234         switch (authdata->algtype) {
235         case OP_ALG_ALGSEL_MD5:
236                 storelen = 16;
237                 break;
238         case OP_ALG_ALGSEL_SHA1:
239                 storelen = 20;
240                 break;
241         case OP_ALG_ALGSEL_SHA224:
242                 storelen = 28;
243                 break;
244         case OP_ALG_ALGSEL_SHA256:
245                 storelen = 32;
246                 break;
247         case OP_ALG_ALGSEL_SHA384:
248                 storelen = 48;
249                 break;
250         case OP_ALG_ALGSEL_SHA512:
251                 storelen = 64;
252                 break;
253         default:
254                 return -EINVAL;
255         }
256
257         trunc_len = trunc_len && (trunc_len < storelen) ? trunc_len : storelen;
258
259         opicv = do_icv ? ICV_CHECK_ENABLE : ICV_CHECK_DISABLE;
260         dir = do_icv ? DIR_DEC : DIR_ENC;
261
262         PROGRAM_CNTXT_INIT(p, descbuf, 0);
263         if (swap)
264                 PROGRAM_SET_BSWAP(p);
265         if (ps)
266                 PROGRAM_SET_36BIT_ADDR(p);
267         SHR_HDR(p, share, 1, SC);
268
269         pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
270         KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
271             INLINE_KEY(authdata));
272
273         /* Do operation */
274         ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC,
275                       OP_ALG_AS_INITFINAL, opicv, dir);
276
277         pjmpprecomp = JUMP(p, jmpprecomp, LOCAL_JUMP, ALL_TRUE, 0);
278         SET_LABEL(p, keyjmp);
279
280         ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
281                       OP_ALG_AS_INITFINAL, opicv, dir);
282
283         SET_LABEL(p, jmpprecomp);
284
285         /* compute sequences */
286         if (opicv == ICV_CHECK_ENABLE)
287                 MATHB(p, SEQINSZ, SUB, trunc_len, VSEQINSZ, 4, IMMED2);
288         else
289                 MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
290
291         /* Do load (variable length) */
292         SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
293
294         if (opicv == ICV_CHECK_ENABLE)
295                 SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
296         else
297                 SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
298
299         PATCH_JUMP(p, pkeyjmp, keyjmp);
300         PATCH_JUMP(p, pjmpprecomp, jmpprecomp);
301
302         return PROGRAM_FINALIZE(p);
303 }
304
305 /**
306  * cnstr_shdsc_kasumi_f8 - KASUMI F8 (Confidentiality) as a shared descriptor
307  *                         (ETSI "Document 1: f8 and f9 specification")
308  * @descbuf: pointer to descriptor-under-construction buffer
309  * @ps: if 36/40bit addressing is desired, this parameter must be true
310  * @swap: must be true when core endianness doesn't match SEC endianness
311  * @cipherdata: pointer to block cipher transform definitions
312  * @dir: cipher direction (DIR_ENC/DIR_DEC)
313  * @count: count value (32 bits)
314  * @bearer: bearer ID (5 bits)
315  * @direction: direction (1 bit)
316  *
317  * Return: size of descriptor written in words or negative number on error
318  */
319 static inline int
320 cnstr_shdsc_kasumi_f8(uint32_t *descbuf, bool ps, bool swap,
321                       struct alginfo *cipherdata, uint8_t dir,
322                       uint32_t count, uint8_t bearer, uint8_t direction)
323 {
324         struct program prg;
325         struct program *p = &prg;
326         uint64_t ct = count;
327         uint64_t br = bearer;
328         uint64_t dr = direction;
329         uint32_t context[2] = { ct, (br << 27) | (dr << 26) };
330
331         PROGRAM_CNTXT_INIT(p, descbuf, 0);
332         if (swap) {
333                 PROGRAM_SET_BSWAP(p);
334
335                 context[0] = swab32(context[0]);
336                 context[1] = swab32(context[1]);
337         }
338         if (ps)
339                 PROGRAM_SET_36BIT_ADDR(p);
340         SHR_HDR(p, SHR_ALWAYS, 1, 0);
341
342         KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
343             cipherdata->keylen, INLINE_KEY(cipherdata));
344         MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
345         MATHB(p, SEQINSZ, SUB, MATH2, VSEQOUTSZ, 4, 0);
346         ALG_OPERATION(p, OP_ALG_ALGSEL_KASUMI, OP_ALG_AAI_F8,
347                       OP_ALG_AS_INITFINAL, 0, dir);
348         LOAD(p, (uintptr_t)context, CONTEXT1, 0, 8, IMMED | COPY);
349         SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1);
350         SEQFIFOSTORE(p, MSG, 0, 0, VLF);
351
352         return PROGRAM_FINALIZE(p);
353 }
354
355 /**
356  * cnstr_shdsc_kasumi_f9 -  KASUMI F9 (Integrity) as a shared descriptor
357  *                          (ETSI "Document 1: f8 and f9 specification")
358  * @descbuf: pointer to descriptor-under-construction buffer
359  * @ps: if 36/40bit addressing is desired, this parameter must be true
360  * @swap: must be true when core endianness doesn't match SEC endianness
361  * @authdata: pointer to authentication transform definitions
362  * @dir: cipher direction (DIR_ENC/DIR_DEC)
363  * @count: count value (32 bits)
364  * @fresh: fresh value ID (32 bits)
365  * @direction: direction (1 bit)
366  * @datalen: size of data
367  *
368  * Return: size of descriptor written in words or negative number on error
369  */
370 static inline int
371 cnstr_shdsc_kasumi_f9(uint32_t *descbuf, bool ps, bool swap,
372                       struct alginfo *authdata, uint8_t dir,
373                       uint32_t count, uint32_t fresh, uint8_t direction,
374                       uint32_t datalen)
375 {
376         struct program prg;
377         struct program *p = &prg;
378         uint16_t ctx_offset = 16;
379         uint32_t context[6] = {count, direction << 26, fresh, 0, 0, 0};
380
381         PROGRAM_CNTXT_INIT(p, descbuf, 0);
382         if (swap) {
383                 PROGRAM_SET_BSWAP(p);
384
385                 context[0] = swab32(context[0]);
386                 context[1] = swab32(context[1]);
387                 context[2] = swab32(context[2]);
388         }
389         if (ps)
390                 PROGRAM_SET_36BIT_ADDR(p);
391         SHR_HDR(p, SHR_ALWAYS, 1, 0);
392
393         KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
394             INLINE_KEY(authdata));
395         MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
396         ALG_OPERATION(p, OP_ALG_ALGSEL_KASUMI, OP_ALG_AAI_F9,
397                       OP_ALG_AS_INITFINAL, 0, dir);
398         LOAD(p, (uintptr_t)context, CONTEXT1, 0, 24, IMMED | COPY);
399         SEQFIFOLOAD(p, BIT_DATA, datalen, CLASS1 | LAST1);
400         /* Save output MAC of DWORD 2 into a 32-bit sequence */
401         SEQSTORE(p, CONTEXT1, ctx_offset, 4, 0);
402
403         return PROGRAM_FINALIZE(p);
404 }
405
406 /**
407  * cnstr_shdsc_crc - CRC32 Accelerator (IEEE 802 CRC32 protocol mode)
408  * @descbuf: pointer to descriptor-under-construction buffer
409  * @swap: must be true when core endianness doesn't match SEC endianness
410  *
411  * Return: size of descriptor written in words or negative number on error
412  */
413 static inline int
414 cnstr_shdsc_crc(uint32_t *descbuf, bool swap)
415 {
416         struct program prg;
417         struct program *p = &prg;
418
419         PROGRAM_CNTXT_INIT(p, descbuf, 0);
420         if (swap)
421                 PROGRAM_SET_BSWAP(p);
422
423         SHR_HDR(p, SHR_ALWAYS, 1, 0);
424
425         MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
426         ALG_OPERATION(p, OP_ALG_ALGSEL_CRC,
427                       OP_ALG_AAI_802 | OP_ALG_AAI_DOC,
428                       OP_ALG_AS_FINALIZE, 0, DIR_ENC);
429         SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
430         SEQSTORE(p, CONTEXT2, 0, 4, 0);
431
432         return PROGRAM_FINALIZE(p);
433 }
434
435 /**
436  * cnstr_shdsc_gcm_encap - AES-GCM encap as a shared descriptor
437  * @descbuf: pointer to descriptor-under-construction buffer
438  * @ps: if 36/40bit addressing is desired, this parameter must be true
439  * @swap: must be true when core endianness doesn't match SEC endianness
440  * @share: sharing type of shared descriptor
441  * @cipherdata: pointer to block cipher transform definitions
442  *              Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with
443  *              OP_ALG_AAI_GCM.
444  * @ivlen: Initialization vector length
445  * @icvsize: integrity check value (ICV) size (truncated or full)
446  *
447  * Return: size of descriptor written in words or negative number on error
448  */
449 static inline int
450 cnstr_shdsc_gcm_encap(uint32_t *descbuf, bool ps, bool swap,
451                       enum rta_share_type share,
452                       struct alginfo *cipherdata,
453                       uint32_t ivlen, uint32_t icvsize)
454 {
455         struct program prg;
456         struct program *p = &prg;
457
458         LABEL(keyjmp);
459         LABEL(zeroassocjump2);
460         LABEL(zeroassocjump1);
461         LABEL(zeropayloadjump);
462         REFERENCE(pkeyjmp);
463         REFERENCE(pzeroassocjump2);
464         REFERENCE(pzeroassocjump1);
465         REFERENCE(pzeropayloadjump);
466
467         PROGRAM_CNTXT_INIT(p, descbuf, 0);
468
469         if (swap)
470                 PROGRAM_SET_BSWAP(p);
471         if (ps)
472                 PROGRAM_SET_36BIT_ADDR(p);
473
474         SHR_HDR(p, share, 1, SC);
475
476         pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SELF | SHRD);
477         /* Insert Key */
478         KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
479             cipherdata->keylen, INLINE_KEY(cipherdata));
480
481         SET_LABEL(p, keyjmp);
482
483         /* class 1 operation */
484         ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
485                       OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
486
487         MATHB(p, DPOVRD, AND, 0x7fffffff, MATH3, 4, IMMED2);
488
489         /* if assoclen + cryptlen is ZERO, skip to ICV write */
490         MATHB(p, SEQINSZ, SUB, ivlen, VSEQOUTSZ, 4, IMMED2);
491         pzeroassocjump2 = JUMP(p, zeroassocjump2, LOCAL_JUMP, ALL_TRUE, MATH_Z);
492
493         SEQFIFOLOAD(p, IV1, ivlen, FLUSH1);
494
495         /* if assoclen is ZERO, skip reading the assoc data */
496         MATHB(p, ZERO, ADD, MATH3, VSEQINSZ, 4, 0);
497         pzeroassocjump1 = JUMP(p, zeroassocjump1, LOCAL_JUMP, ALL_TRUE, MATH_Z);
498
499         MATHB(p, ZERO, ADD, MATH3, VSEQOUTSZ, 4, 0);
500
501         /* skip assoc data */
502         SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
503
504         /* cryptlen = seqinlen - assoclen */
505         MATHB(p, SEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
506
507         /* if cryptlen is ZERO jump to zero-payload commands */
508         pzeropayloadjump = JUMP(p, zeropayloadjump, LOCAL_JUMP, ALL_TRUE,
509                                 MATH_Z);
510
511         /* read assoc data */
512         SEQFIFOLOAD(p, AAD1, 0, CLASS1 | VLF | FLUSH1);
513         SET_LABEL(p, zeroassocjump1);
514
515         MATHB(p, SEQINSZ, SUB, MATH0, VSEQINSZ, 4, 0);
516
517         /* write encrypted data */
518         SEQFIFOSTORE(p, MSG, 0, 0, VLF);
519
520         /* read payload data */
521         SEQFIFOLOAD(p, MSG1, 0, CLASS1 | VLF | LAST1);
522
523         /* jump the zero-payload commands */
524         JUMP(p, 4, LOCAL_JUMP, ALL_TRUE, 0);
525
526         /* zero-payload commands */
527         SET_LABEL(p, zeropayloadjump);
528
529         /* read assoc data */
530         SEQFIFOLOAD(p, AAD1, 0, CLASS1 | VLF | LAST1);
531
532         JUMP(p, 2, LOCAL_JUMP, ALL_TRUE, 0);
533
534         /* There is no input data */
535         SET_LABEL(p, zeroassocjump2);
536
537         SEQFIFOLOAD(p, IV1, ivlen, FLUSH1 | LAST1);
538
539         /* write ICV */
540         SEQSTORE(p, CONTEXT1, 0, icvsize, 0);
541
542         PATCH_JUMP(p, pkeyjmp, keyjmp);
543         PATCH_JUMP(p, pzeroassocjump2, zeroassocjump2);
544         PATCH_JUMP(p, pzeroassocjump1, zeroassocjump1);
545         PATCH_JUMP(p, pzeropayloadjump, zeropayloadjump);
546
547         return PROGRAM_FINALIZE(p);
548 }
549
550 /**
551  * cnstr_shdsc_gcm_decap - AES-GCM decap as a shared descriptor
552  * @descbuf: pointer to descriptor-under-construction buffer
553  * @ps: if 36/40bit addressing is desired, this parameter must be true
554  * @swap: must be true when core endianness doesn't match SEC endianness
555  * @share: sharing type of shared descriptor
556  * @cipherdata: pointer to block cipher transform definitions
557  *              Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with
558  *              OP_ALG_AAI_GCM.
559  * @icvsize: integrity check value (ICV) size (truncated or full)
560  *
561  * Return: size of descriptor written in words or negative number on error
562  */
563 static inline int
564 cnstr_shdsc_gcm_decap(uint32_t *descbuf, bool ps, bool swap,
565                       enum rta_share_type share,
566                       struct alginfo *cipherdata,
567                       uint32_t ivlen, uint32_t icvsize)
568 {
569         struct program prg;
570         struct program *p = &prg;
571
572         LABEL(keyjmp);
573         LABEL(zeroassocjump1);
574         LABEL(zeropayloadjump);
575         REFERENCE(pkeyjmp);
576         REFERENCE(pzeroassocjump1);
577         REFERENCE(pzeropayloadjump);
578
579         PROGRAM_CNTXT_INIT(p, descbuf, 0);
580
581         if (swap)
582                 PROGRAM_SET_BSWAP(p);
583         if (ps)
584                 PROGRAM_SET_36BIT_ADDR(p);
585
586         SHR_HDR(p, share, 1, SC);
587
588         pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SELF | SHRD);
589         /* Insert Key */
590         KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
591             cipherdata->keylen, INLINE_KEY(cipherdata));
592
593         SET_LABEL(p, keyjmp);
594
595         /* class 1 operation */
596         ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
597                       OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
598
599         MATHB(p, DPOVRD, AND, 0x7fffffff, MATH3, 4, IMMED2);
600         SEQFIFOLOAD(p, IV1, ivlen, FLUSH1);
601
602         /* if assoclen is ZERO, skip reading the assoc data */
603         MATHB(p, ZERO, ADD, MATH3, VSEQINSZ, 4, 0);
604         pzeroassocjump1 = JUMP(p, zeroassocjump1, LOCAL_JUMP, ALL_TRUE, MATH_Z);
605
606         MATHB(p, ZERO, ADD, MATH3, VSEQOUTSZ, 4, 0);
607
608         /* skip assoc data */
609         SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
610
611         /* read assoc data */
612         SEQFIFOLOAD(p, AAD1, 0, CLASS1 | VLF | FLUSH1);
613
614         SET_LABEL(p, zeroassocjump1);
615
616         /* cryptlen = seqoutlen - assoclen */
617         MATHB(p, SEQOUTSZ, SUB, MATH0, VSEQINSZ, 4, 0);
618
619         /* jump to zero-payload command if cryptlen is zero */
620         pzeropayloadjump = JUMP(p, zeropayloadjump, LOCAL_JUMP, ALL_TRUE,
621                                 MATH_Z);
622
623         MATHB(p, SEQOUTSZ, SUB, MATH0, VSEQOUTSZ, 4, 0);
624
625         /* store encrypted data */
626         SEQFIFOSTORE(p, MSG, 0, 0, VLF);
627
628         /* read payload data */
629         SEQFIFOLOAD(p, MSG1, 0, CLASS1 | VLF | FLUSH1);
630
631         /* zero-payload command */
632         SET_LABEL(p, zeropayloadjump);
633
634         /* read ICV */
635         SEQFIFOLOAD(p, ICV1, icvsize, CLASS1 | LAST1);
636
637         PATCH_JUMP(p, pkeyjmp, keyjmp);
638         PATCH_JUMP(p, pzeroassocjump1, zeroassocjump1);
639         PATCH_JUMP(p, pzeropayloadjump, zeropayloadjump);
640
641         return PROGRAM_FINALIZE(p);
642 }
643
644 #endif /* __DESC_ALGO_H__ */