1c0ded849SHemant Agrawal /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2c0ded849SHemant Agrawal *
3c0ded849SHemant Agrawal * Copyright 2008-2016 Freescale Semiconductor Inc.
483087a92SHemant Agrawal * Copyright 2016,2019-2021 NXP
5c0ded849SHemant Agrawal *
6c0ded849SHemant Agrawal */
7c0ded849SHemant Agrawal
8c0ded849SHemant Agrawal #ifndef __DESC_ALGO_H__
9c0ded849SHemant Agrawal #define __DESC_ALGO_H__
10c0ded849SHemant Agrawal
11c0ded849SHemant Agrawal #include "rta.h"
12c0ded849SHemant Agrawal #include "common.h"
13c0ded849SHemant Agrawal
14c0ded849SHemant Agrawal /**
15c0ded849SHemant Agrawal * DOC: Algorithms - Shared Descriptor Constructors
16c0ded849SHemant Agrawal *
17c0ded849SHemant Agrawal * Shared descriptors for algorithms (i.e. not for protocols).
18c0ded849SHemant Agrawal */
19c0ded849SHemant Agrawal
20c0ded849SHemant Agrawal /**
21c0ded849SHemant Agrawal * cnstr_shdsc_zuce - ZUC Enc (EEA2) as a shared descriptor
22c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
23c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
24c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
25c0ded849SHemant Agrawal * @cipherdata: pointer to block cipher transform definitions
26c0ded849SHemant Agrawal * @dir: Cipher direction (DIR_ENC/DIR_DEC)
27c0ded849SHemant Agrawal *
28c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
29c0ded849SHemant Agrawal */
30c0ded849SHemant Agrawal static inline int
cnstr_shdsc_zuce(uint32_t * descbuf,bool ps,bool swap,struct alginfo * cipherdata,uint8_t dir)31c0ded849SHemant Agrawal cnstr_shdsc_zuce(uint32_t *descbuf, bool ps, bool swap,
32c0ded849SHemant Agrawal struct alginfo *cipherdata, uint8_t dir)
33c0ded849SHemant Agrawal {
34c0ded849SHemant Agrawal struct program prg;
35c0ded849SHemant Agrawal struct program *p = &prg;
36c0ded849SHemant Agrawal
37c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
38c0ded849SHemant Agrawal if (swap)
39c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
40c0ded849SHemant Agrawal
41c0ded849SHemant Agrawal if (ps)
42c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
43c0ded849SHemant Agrawal SHR_HDR(p, SHR_ALWAYS, 1, 0);
44c0ded849SHemant Agrawal
45c0ded849SHemant Agrawal KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
46c0ded849SHemant Agrawal cipherdata->keylen, INLINE_KEY(cipherdata));
47c0ded849SHemant Agrawal
48c0ded849SHemant Agrawal SEQLOAD(p, CONTEXT1, 0, 16, 0);
49c0ded849SHemant Agrawal
50c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
51c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQOUTSZ, 4, 0);
52c0ded849SHemant Agrawal ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8,
53c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, 0, dir);
54c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1);
55c0ded849SHemant Agrawal SEQFIFOSTORE(p, MSG, 0, 0, VLF);
56c0ded849SHemant Agrawal
57c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
58c0ded849SHemant Agrawal }
59c0ded849SHemant Agrawal
60c0ded849SHemant Agrawal /**
61c0ded849SHemant Agrawal * cnstr_shdsc_zuca - ZUC Auth (EIA2) as a shared descriptor
62c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
63c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
64c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
65c0ded849SHemant Agrawal * @authdata: pointer to authentication transform definitions
66c0ded849SHemant Agrawal * @chk_icv: Whether to compare and verify ICV (true/false)
67c0ded849SHemant Agrawal * @authlen: size of digest
68c0ded849SHemant Agrawal *
69c0ded849SHemant Agrawal * The IV prepended before hmac payload must be 8 bytes consisting
70*7be78d02SJosh Soref * of COUNT||BEARER||DIR. The COUNT is of 32-bits, bearer is of 5 bits and
71c0ded849SHemant Agrawal * direction is of 1 bit - totalling to 38 bits.
72c0ded849SHemant Agrawal *
73c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
74c0ded849SHemant Agrawal */
75c0ded849SHemant Agrawal static inline int
cnstr_shdsc_zuca(uint32_t * descbuf,bool ps,bool swap,struct alginfo * authdata,uint8_t chk_icv,uint32_t authlen)76c0ded849SHemant Agrawal cnstr_shdsc_zuca(uint32_t *descbuf, bool ps, bool swap,
77c0ded849SHemant Agrawal struct alginfo *authdata, uint8_t chk_icv,
78c0ded849SHemant Agrawal uint32_t authlen)
79c0ded849SHemant Agrawal {
80c0ded849SHemant Agrawal struct program prg;
81c0ded849SHemant Agrawal struct program *p = &prg;
82c0ded849SHemant Agrawal int dir = chk_icv ? DIR_DEC : DIR_ENC;
83c0ded849SHemant Agrawal
84c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
85c0ded849SHemant Agrawal if (swap)
86c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
87c0ded849SHemant Agrawal
88c0ded849SHemant Agrawal if (ps)
89c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
90c0ded849SHemant Agrawal SHR_HDR(p, SHR_ALWAYS, 1, 0);
91c0ded849SHemant Agrawal
92c0ded849SHemant Agrawal KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
93c0ded849SHemant Agrawal authdata->keylen, INLINE_KEY(authdata));
94c0ded849SHemant Agrawal
95c0ded849SHemant Agrawal SEQLOAD(p, CONTEXT2, 0, 8, 0);
96c0ded849SHemant Agrawal
97c0ded849SHemant Agrawal if (chk_icv == ICV_CHECK_ENABLE)
98c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, authlen, VSEQINSZ, 4, IMMED2);
99c0ded849SHemant Agrawal else
100c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
101c0ded849SHemant Agrawal
102c0ded849SHemant Agrawal ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA, OP_ALG_AAI_F9,
103c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, chk_icv, dir);
104c0ded849SHemant Agrawal
105c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG2, 0, VLF | CLASS2 | LAST2);
106c0ded849SHemant Agrawal
107c0ded849SHemant Agrawal if (chk_icv == ICV_CHECK_ENABLE)
108c0ded849SHemant Agrawal SEQFIFOLOAD(p, ICV2, authlen, LAST2);
109c0ded849SHemant Agrawal else
110c0ded849SHemant Agrawal /* Save lower half of MAC out into a 32-bit sequence */
111c0ded849SHemant Agrawal SEQSTORE(p, CONTEXT2, 0, authlen, 0);
112c0ded849SHemant Agrawal
113c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
114c0ded849SHemant Agrawal }
115c0ded849SHemant Agrawal
116c0ded849SHemant Agrawal
117c0ded849SHemant Agrawal /**
118c0ded849SHemant Agrawal * cnstr_shdsc_snow_f8 - SNOW/f8 (UEA2) as a shared descriptor
119c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
120c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
121c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
122c0ded849SHemant Agrawal * @cipherdata: pointer to block cipher transform definitions
123c0ded849SHemant Agrawal * @dir: Cipher direction (DIR_ENC/DIR_DEC)
124c0ded849SHemant Agrawal *
125c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
126c0ded849SHemant Agrawal */
127c0ded849SHemant Agrawal static inline int
cnstr_shdsc_snow_f8(uint32_t * descbuf,bool ps,bool swap,struct alginfo * cipherdata,uint8_t dir)128c0ded849SHemant Agrawal cnstr_shdsc_snow_f8(uint32_t *descbuf, bool ps, bool swap,
129c0ded849SHemant Agrawal struct alginfo *cipherdata, uint8_t dir)
130c0ded849SHemant Agrawal {
131c0ded849SHemant Agrawal struct program prg;
132c0ded849SHemant Agrawal struct program *p = &prg;
133c0ded849SHemant Agrawal
134c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
135c0ded849SHemant Agrawal if (swap)
136c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
137c0ded849SHemant Agrawal
138c0ded849SHemant Agrawal if (ps)
139c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
140c0ded849SHemant Agrawal SHR_HDR(p, SHR_ALWAYS, 1, 0);
141c0ded849SHemant Agrawal
142c0ded849SHemant Agrawal KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
143c0ded849SHemant Agrawal cipherdata->keylen, INLINE_KEY(cipherdata));
144c0ded849SHemant Agrawal
145c0ded849SHemant Agrawal SEQLOAD(p, CONTEXT1, 0, 16, 0);
146c0ded849SHemant Agrawal
147c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
148c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQOUTSZ, 4, 0);
149c0ded849SHemant Agrawal ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8,
150c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, 0, dir);
151c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1);
152c0ded849SHemant Agrawal SEQFIFOSTORE(p, MSG, 0, 0, VLF);
153c0ded849SHemant Agrawal
154c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
155c0ded849SHemant Agrawal }
156c0ded849SHemant Agrawal
157c0ded849SHemant Agrawal /**
158c0ded849SHemant Agrawal * conv_to_zuc_eia_iv - ZUCA IV 16-byte to 8-byte convert
159c0ded849SHemant Agrawal * function for 3G.
160c0ded849SHemant Agrawal * @iv: 16 bytes of original IV data.
161c0ded849SHemant Agrawal *
162c0ded849SHemant Agrawal * From the original IV, we extract 32-bits of COUNT,
163c0ded849SHemant Agrawal * 5-bits of bearer and 1-bit of direction.
164c0ded849SHemant Agrawal * Refer to CAAM refman for ZUCA IV format. Then these values are
165c0ded849SHemant Agrawal * appended as COUNT||BEARER||DIR continuously to make a 38-bit block.
166c0ded849SHemant Agrawal * This 38-bit block is copied left justified into 8-byte array used as
167c0ded849SHemant Agrawal * converted IV.
168c0ded849SHemant Agrawal *
169c0ded849SHemant Agrawal * Return: 8-bytes of IV data as understood by SEC HW
170c0ded849SHemant Agrawal */
171c0ded849SHemant Agrawal
conv_to_zuc_eia_iv(uint8_t * iv)172c0ded849SHemant Agrawal static inline uint8_t *conv_to_zuc_eia_iv(uint8_t *iv)
173c0ded849SHemant Agrawal {
174c0ded849SHemant Agrawal uint8_t dir = (iv[14] & 0x80) ? 4 : 0;
175c0ded849SHemant Agrawal
176c0ded849SHemant Agrawal iv[12] = iv[4] | dir;
177c0ded849SHemant Agrawal iv[13] = 0;
178c0ded849SHemant Agrawal iv[14] = 0;
179c0ded849SHemant Agrawal iv[15] = 0;
180c0ded849SHemant Agrawal
181c0ded849SHemant Agrawal iv[8] = iv[0];
182c0ded849SHemant Agrawal iv[9] = iv[1];
183c0ded849SHemant Agrawal iv[10] = iv[2];
184c0ded849SHemant Agrawal iv[11] = iv[3];
185c0ded849SHemant Agrawal
186c0ded849SHemant Agrawal return (iv + 8);
187c0ded849SHemant Agrawal }
188c0ded849SHemant Agrawal
189c0ded849SHemant Agrawal /**
190c0ded849SHemant Agrawal * conv_to_snow_f9_iv - SNOW/f9 (UIA2) IV 16 byte to 12 byte convert
191c0ded849SHemant Agrawal * function for 3G.
192c0ded849SHemant Agrawal * @iv: 16 byte original IV data
193c0ded849SHemant Agrawal *
194c0ded849SHemant Agrawal * Return: 12 byte IV data as understood by SEC HW
195c0ded849SHemant Agrawal */
196c0ded849SHemant Agrawal
conv_to_snow_f9_iv(uint8_t * iv)197c0ded849SHemant Agrawal static inline uint8_t *conv_to_snow_f9_iv(uint8_t *iv)
198c0ded849SHemant Agrawal {
199c0ded849SHemant Agrawal uint8_t temp = (iv[8] == iv[0]) ? 0 : 4;
200c0ded849SHemant Agrawal
201c0ded849SHemant Agrawal iv[12] = iv[4];
202c0ded849SHemant Agrawal iv[13] = iv[5];
203c0ded849SHemant Agrawal iv[14] = iv[6];
204c0ded849SHemant Agrawal iv[15] = iv[7];
205c0ded849SHemant Agrawal
206c0ded849SHemant Agrawal iv[8] = temp;
207c0ded849SHemant Agrawal iv[9] = 0x00;
208c0ded849SHemant Agrawal iv[10] = 0x00;
209c0ded849SHemant Agrawal iv[11] = 0x00;
210c0ded849SHemant Agrawal
211c0ded849SHemant Agrawal iv[4] = iv[0];
212c0ded849SHemant Agrawal iv[5] = iv[1];
213c0ded849SHemant Agrawal iv[6] = iv[2];
214c0ded849SHemant Agrawal iv[7] = iv[3];
215c0ded849SHemant Agrawal
216c0ded849SHemant Agrawal return (iv + 4);
217c0ded849SHemant Agrawal }
218c0ded849SHemant Agrawal
219c0ded849SHemant Agrawal /**
220c0ded849SHemant Agrawal * cnstr_shdsc_snow_f9 - SNOW/f9 (UIA2) as a shared descriptor
221c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
222c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
223c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
224c0ded849SHemant Agrawal * @authdata: pointer to authentication transform definitions
225c0ded849SHemant Agrawal * @chk_icv: check or generate ICV value
226c0ded849SHemant Agrawal * @authlen: size of digest
227c0ded849SHemant Agrawal *
228c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
229c0ded849SHemant Agrawal */
230c0ded849SHemant Agrawal static inline int
cnstr_shdsc_snow_f9(uint32_t * descbuf,bool ps,bool swap,struct alginfo * authdata,uint8_t chk_icv,uint32_t authlen)231c0ded849SHemant Agrawal cnstr_shdsc_snow_f9(uint32_t *descbuf, bool ps, bool swap,
232c0ded849SHemant Agrawal struct alginfo *authdata, uint8_t chk_icv,
233c0ded849SHemant Agrawal uint32_t authlen)
234c0ded849SHemant Agrawal {
235c0ded849SHemant Agrawal struct program prg;
236c0ded849SHemant Agrawal struct program *p = &prg;
237c0ded849SHemant Agrawal int dir = chk_icv ? DIR_DEC : DIR_ENC;
238c0ded849SHemant Agrawal
239c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
240c0ded849SHemant Agrawal if (swap)
241c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
242c0ded849SHemant Agrawal
243c0ded849SHemant Agrawal if (ps)
244c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
245c0ded849SHemant Agrawal
246c0ded849SHemant Agrawal SHR_HDR(p, SHR_ALWAYS, 1, 0);
247c0ded849SHemant Agrawal
248c0ded849SHemant Agrawal KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
249c0ded849SHemant Agrawal authdata->keylen, INLINE_KEY(authdata));
250c0ded849SHemant Agrawal
251c0ded849SHemant Agrawal SEQLOAD(p, CONTEXT2, 0, 12, 0);
252c0ded849SHemant Agrawal
253c0ded849SHemant Agrawal if (chk_icv == ICV_CHECK_ENABLE)
254c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, authlen, VSEQINSZ, 4, IMMED2);
255c0ded849SHemant Agrawal else
256c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
257c0ded849SHemant Agrawal
258c0ded849SHemant Agrawal ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9, OP_ALG_AAI_F9,
259c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, chk_icv, dir);
260c0ded849SHemant Agrawal
261c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG2, 0, VLF | CLASS2 | LAST2);
262c0ded849SHemant Agrawal
263c0ded849SHemant Agrawal if (chk_icv == ICV_CHECK_ENABLE)
264c0ded849SHemant Agrawal SEQFIFOLOAD(p, ICV2, authlen, LAST2);
265c0ded849SHemant Agrawal else
266c0ded849SHemant Agrawal /* Save lower half of MAC out into a 32-bit sequence */
267c0ded849SHemant Agrawal SEQSTORE(p, CONTEXT2, 0, authlen, 0);
268c0ded849SHemant Agrawal
269c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
270c0ded849SHemant Agrawal }
271c0ded849SHemant Agrawal
272c0ded849SHemant Agrawal /**
273c0ded849SHemant Agrawal * cnstr_shdsc_blkcipher - block cipher transformation
274c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
275c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
276c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
277c0ded849SHemant Agrawal * @share: sharing type of shared descriptor
278c0ded849SHemant Agrawal * @cipherdata: pointer to block cipher transform definitions
279c0ded849SHemant Agrawal * Valid algorithm values one of OP_ALG_ALGSEL_* {DES, 3DES, AES}
280c0ded849SHemant Agrawal * Valid modes for:
281c0ded849SHemant Agrawal * AES: OP_ALG_AAI_* {CBC, CTR}
282c0ded849SHemant Agrawal * DES, 3DES: OP_ALG_AAI_CBC
283c0ded849SHemant Agrawal * @iv: IV data; if NULL, "ivlen" bytes from the input frame will be read as IV
284c0ded849SHemant Agrawal * @ivlen: IV length
285c0ded849SHemant Agrawal * @dir: DIR_ENC/DIR_DEC
286c0ded849SHemant Agrawal *
287c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
288c0ded849SHemant Agrawal */
289c0ded849SHemant Agrawal static inline int
cnstr_shdsc_blkcipher(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct alginfo * cipherdata,uint32_t ivlen,uint8_t dir)290c0ded849SHemant Agrawal cnstr_shdsc_blkcipher(uint32_t *descbuf, bool ps, bool swap,
291c0ded849SHemant Agrawal enum rta_share_type share,
2925906b0adSVakul Garg struct alginfo *cipherdata,
293c0ded849SHemant Agrawal uint32_t ivlen, uint8_t dir)
294c0ded849SHemant Agrawal {
295c0ded849SHemant Agrawal struct program prg;
296c0ded849SHemant Agrawal struct program *p = &prg;
2975906b0adSVakul Garg uint32_t iv_off = 0, counter;
298c0ded849SHemant Agrawal const bool need_dk = (dir == DIR_DEC) &&
299c0ded849SHemant Agrawal (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
300c0ded849SHemant Agrawal (cipherdata->algmode == OP_ALG_AAI_CBC);
301c0ded849SHemant Agrawal LABEL(keyjmp);
302c0ded849SHemant Agrawal LABEL(skipdk);
303c0ded849SHemant Agrawal REFERENCE(pkeyjmp);
304c0ded849SHemant Agrawal REFERENCE(pskipdk);
305c0ded849SHemant Agrawal
306c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
307c0ded849SHemant Agrawal if (swap)
308c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
309c0ded849SHemant Agrawal if (ps)
310c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
311c0ded849SHemant Agrawal SHR_HDR(p, share, 1, SC);
312c0ded849SHemant Agrawal
313c0ded849SHemant Agrawal pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
314c0ded849SHemant Agrawal /* Insert Key */
315c0ded849SHemant Agrawal KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
316c0ded849SHemant Agrawal cipherdata->keylen, INLINE_KEY(cipherdata));
317c0ded849SHemant Agrawal
318c0ded849SHemant Agrawal if (need_dk) {
319c0ded849SHemant Agrawal ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
320c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
321c0ded849SHemant Agrawal
322c0ded849SHemant Agrawal pskipdk = JUMP(p, skipdk, LOCAL_JUMP, ALL_TRUE, 0);
323c0ded849SHemant Agrawal }
324c0ded849SHemant Agrawal SET_LABEL(p, keyjmp);
325c0ded849SHemant Agrawal
326c0ded849SHemant Agrawal if (need_dk) {
327c0ded849SHemant Agrawal ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode |
328c0ded849SHemant Agrawal OP_ALG_AAI_DK, OP_ALG_AS_INITFINAL,
329c0ded849SHemant Agrawal ICV_CHECK_DISABLE, dir);
330c0ded849SHemant Agrawal SET_LABEL(p, skipdk);
331c0ded849SHemant Agrawal } else {
332c0ded849SHemant Agrawal ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
333c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
334c0ded849SHemant Agrawal }
335c0ded849SHemant Agrawal
336c0ded849SHemant Agrawal if (cipherdata->algmode == OP_ALG_AAI_CTR)
337c0ded849SHemant Agrawal iv_off = 16;
338c0ded849SHemant Agrawal
339c0ded849SHemant Agrawal /* IV is present first before the actual message */
340c0ded849SHemant Agrawal SEQLOAD(p, CONTEXT1, iv_off, ivlen, 0);
341c0ded849SHemant Agrawal
3425906b0adSVakul Garg /* If IV len is less than 16 bytes, set 'counter' as 1 */
3435906b0adSVakul Garg if (cipherdata->algmode == OP_ALG_AAI_CTR && ivlen < 16) {
3445906b0adSVakul Garg counter = 1;
3455906b0adSVakul Garg if (!swap)
3465906b0adSVakul Garg counter = swab32(1);
3475906b0adSVakul Garg
3485906b0adSVakul Garg LOAD(p, counter, CONTEXT1, (iv_off + ivlen), 16 - ivlen, IMMED);
3495906b0adSVakul Garg }
3505906b0adSVakul Garg
351c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
352c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQOUTSZ, 4, 0);
353c0ded849SHemant Agrawal
354c0ded849SHemant Agrawal /* Insert sequence load/store with VLF */
355c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1);
356c0ded849SHemant Agrawal SEQFIFOSTORE(p, MSG, 0, 0, VLF);
357c0ded849SHemant Agrawal
358c0ded849SHemant Agrawal PATCH_JUMP(p, pkeyjmp, keyjmp);
359c0ded849SHemant Agrawal if (need_dk)
360c0ded849SHemant Agrawal PATCH_JUMP(p, pskipdk, skipdk);
361c0ded849SHemant Agrawal
362c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
363c0ded849SHemant Agrawal }
364c0ded849SHemant Agrawal
365c0ded849SHemant Agrawal /**
366c0ded849SHemant Agrawal * cnstr_shdsc_hmac - HMAC shared
367c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
368c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
369c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
370c0ded849SHemant Agrawal * @share: sharing type of shared descriptor
371c0ded849SHemant Agrawal * @authdata: pointer to authentication transform definitions;
372c0ded849SHemant Agrawal * message digest algorithm: OP_ALG_ALGSEL_MD5/ SHA1-512.
373c0ded849SHemant Agrawal * @do_icv: 0 if ICV checking is not desired, any other value if ICV checking
374c0ded849SHemant Agrawal * is needed for all the packets processed by this shared descriptor
375c0ded849SHemant Agrawal * @trunc_len: Length of the truncated ICV to be written in the output buffer, 0
376c0ded849SHemant Agrawal * if no truncation is needed
377c0ded849SHemant Agrawal *
378c0ded849SHemant Agrawal * Note: There's no support for keys longer than the block size of the
379c0ded849SHemant Agrawal * underlying hash function, according to the selected algorithm.
380c0ded849SHemant Agrawal *
381c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
382c0ded849SHemant Agrawal */
383c0ded849SHemant Agrawal static inline int
cnstr_shdsc_hmac(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct alginfo * authdata,uint8_t do_icv,uint8_t trunc_len)384c0ded849SHemant Agrawal cnstr_shdsc_hmac(uint32_t *descbuf, bool ps, bool swap,
385c0ded849SHemant Agrawal enum rta_share_type share,
386c0ded849SHemant Agrawal struct alginfo *authdata, uint8_t do_icv,
387c0ded849SHemant Agrawal uint8_t trunc_len)
388c0ded849SHemant Agrawal {
389c0ded849SHemant Agrawal struct program prg;
390c0ded849SHemant Agrawal struct program *p = &prg;
391c0ded849SHemant Agrawal uint8_t storelen, opicv, dir;
392c0ded849SHemant Agrawal LABEL(keyjmp);
393c0ded849SHemant Agrawal LABEL(jmpprecomp);
394c0ded849SHemant Agrawal REFERENCE(pkeyjmp);
395c0ded849SHemant Agrawal REFERENCE(pjmpprecomp);
396c0ded849SHemant Agrawal
397c0ded849SHemant Agrawal /* Compute fixed-size store based on alg selection */
398c0ded849SHemant Agrawal switch (authdata->algtype) {
399c0ded849SHemant Agrawal case OP_ALG_ALGSEL_MD5:
400c0ded849SHemant Agrawal storelen = 16;
401c0ded849SHemant Agrawal break;
402c0ded849SHemant Agrawal case OP_ALG_ALGSEL_SHA1:
403c0ded849SHemant Agrawal storelen = 20;
404c0ded849SHemant Agrawal break;
405c0ded849SHemant Agrawal case OP_ALG_ALGSEL_SHA224:
406c0ded849SHemant Agrawal storelen = 28;
407c0ded849SHemant Agrawal break;
408c0ded849SHemant Agrawal case OP_ALG_ALGSEL_SHA256:
409c0ded849SHemant Agrawal storelen = 32;
410c0ded849SHemant Agrawal break;
411c0ded849SHemant Agrawal case OP_ALG_ALGSEL_SHA384:
412c0ded849SHemant Agrawal storelen = 48;
413c0ded849SHemant Agrawal break;
414c0ded849SHemant Agrawal case OP_ALG_ALGSEL_SHA512:
415c0ded849SHemant Agrawal storelen = 64;
416c0ded849SHemant Agrawal break;
417c0ded849SHemant Agrawal default:
418c0ded849SHemant Agrawal return -EINVAL;
419c0ded849SHemant Agrawal }
420c0ded849SHemant Agrawal
421c0ded849SHemant Agrawal trunc_len = trunc_len && (trunc_len < storelen) ? trunc_len : storelen;
422c0ded849SHemant Agrawal
423c0ded849SHemant Agrawal opicv = do_icv ? ICV_CHECK_ENABLE : ICV_CHECK_DISABLE;
424c0ded849SHemant Agrawal dir = do_icv ? DIR_DEC : DIR_ENC;
425c0ded849SHemant Agrawal
426c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
427c0ded849SHemant Agrawal if (swap)
428c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
429c0ded849SHemant Agrawal if (ps)
430c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
431c0ded849SHemant Agrawal SHR_HDR(p, share, 1, SC);
432c0ded849SHemant Agrawal
433c0ded849SHemant Agrawal pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
434c0ded849SHemant Agrawal KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
435c0ded849SHemant Agrawal INLINE_KEY(authdata));
436c0ded849SHemant Agrawal
437c0ded849SHemant Agrawal /* Do operation */
438c0ded849SHemant Agrawal ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC,
439c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, opicv, dir);
440c0ded849SHemant Agrawal
441c0ded849SHemant Agrawal pjmpprecomp = JUMP(p, jmpprecomp, LOCAL_JUMP, ALL_TRUE, 0);
442c0ded849SHemant Agrawal SET_LABEL(p, keyjmp);
443c0ded849SHemant Agrawal
444c0ded849SHemant Agrawal ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
445c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, opicv, dir);
446c0ded849SHemant Agrawal
447c0ded849SHemant Agrawal SET_LABEL(p, jmpprecomp);
448c0ded849SHemant Agrawal
449c0ded849SHemant Agrawal /* compute sequences */
450c0ded849SHemant Agrawal if (opicv == ICV_CHECK_ENABLE)
451c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, trunc_len, VSEQINSZ, 4, IMMED2);
452c0ded849SHemant Agrawal else
453c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
454c0ded849SHemant Agrawal
455c0ded849SHemant Agrawal /* Do load (variable length) */
456c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
457c0ded849SHemant Agrawal
458c0ded849SHemant Agrawal if (opicv == ICV_CHECK_ENABLE)
459c0ded849SHemant Agrawal SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
460c0ded849SHemant Agrawal else
461c0ded849SHemant Agrawal SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
462c0ded849SHemant Agrawal
463c0ded849SHemant Agrawal PATCH_JUMP(p, pkeyjmp, keyjmp);
464c0ded849SHemant Agrawal PATCH_JUMP(p, pjmpprecomp, jmpprecomp);
465c0ded849SHemant Agrawal
466c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
467c0ded849SHemant Agrawal }
468c0ded849SHemant Agrawal
469c0ded849SHemant Agrawal /**
470a054c627SAkhil Goyal * cnstr_shdsc_hash - HASH shared
471a054c627SAkhil Goyal * @descbuf: pointer to descriptor-under-construction buffer
472a054c627SAkhil Goyal * @ps: if 36/40bit addressing is desired, this parameter must be true
473a054c627SAkhil Goyal * @swap: must be true when core endianness doesn't match SEC endianness
474a054c627SAkhil Goyal * @share: sharing type of shared descriptor
475a054c627SAkhil Goyal * @authdata: pointer to authentication transform definitions;
476a054c627SAkhil Goyal * message digest algorithm: OP_ALG_ALGSEL_MD5/ SHA1-512.
477a054c627SAkhil Goyal * @do_icv: 0 if ICV checking is not desired, any other value if ICV checking
478a054c627SAkhil Goyal * is needed for all the packets processed by this shared descriptor
479a054c627SAkhil Goyal * @trunc_len: Length of the truncated ICV to be written in the output buffer, 0
480a054c627SAkhil Goyal * if no truncation is needed
481a054c627SAkhil Goyal *
482a054c627SAkhil Goyal * Note: There's no support for keys longer than the block size of the
483a054c627SAkhil Goyal * underlying hash function, according to the selected algorithm.
484a054c627SAkhil Goyal *
485a054c627SAkhil Goyal * Return: size of descriptor written in words or negative number on error
486a054c627SAkhil Goyal */
487a054c627SAkhil Goyal static inline int
cnstr_shdsc_hash(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct alginfo * authdata,uint8_t do_icv,uint8_t trunc_len)488a054c627SAkhil Goyal cnstr_shdsc_hash(uint32_t *descbuf, bool ps, bool swap,
489a054c627SAkhil Goyal enum rta_share_type share,
490a054c627SAkhil Goyal struct alginfo *authdata, uint8_t do_icv,
491a054c627SAkhil Goyal uint8_t trunc_len)
492a054c627SAkhil Goyal {
493a054c627SAkhil Goyal struct program prg;
494a054c627SAkhil Goyal struct program *p = &prg;
495a054c627SAkhil Goyal uint8_t storelen, opicv, dir;
496a054c627SAkhil Goyal
497a054c627SAkhil Goyal /* Compute fixed-size store based on alg selection */
498a054c627SAkhil Goyal switch (authdata->algtype) {
499a054c627SAkhil Goyal case OP_ALG_ALGSEL_MD5:
500a054c627SAkhil Goyal storelen = 16;
501a054c627SAkhil Goyal break;
502a054c627SAkhil Goyal case OP_ALG_ALGSEL_SHA1:
503a054c627SAkhil Goyal storelen = 20;
504a054c627SAkhil Goyal break;
505a054c627SAkhil Goyal case OP_ALG_ALGSEL_SHA224:
506a054c627SAkhil Goyal storelen = 28;
507a054c627SAkhil Goyal break;
508a054c627SAkhil Goyal case OP_ALG_ALGSEL_SHA256:
509a054c627SAkhil Goyal storelen = 32;
510a054c627SAkhil Goyal break;
511a054c627SAkhil Goyal case OP_ALG_ALGSEL_SHA384:
512a054c627SAkhil Goyal storelen = 48;
513a054c627SAkhil Goyal break;
514a054c627SAkhil Goyal case OP_ALG_ALGSEL_SHA512:
515a054c627SAkhil Goyal storelen = 64;
516a054c627SAkhil Goyal break;
517a054c627SAkhil Goyal default:
518a054c627SAkhil Goyal return -EINVAL;
519a054c627SAkhil Goyal }
520a054c627SAkhil Goyal
521a054c627SAkhil Goyal trunc_len = trunc_len && (trunc_len < storelen) ? trunc_len : storelen;
522a054c627SAkhil Goyal
523a054c627SAkhil Goyal opicv = do_icv ? ICV_CHECK_ENABLE : ICV_CHECK_DISABLE;
524a054c627SAkhil Goyal dir = do_icv ? DIR_DEC : DIR_ENC;
525a054c627SAkhil Goyal
526a054c627SAkhil Goyal PROGRAM_CNTXT_INIT(p, descbuf, 0);
527a054c627SAkhil Goyal if (swap)
528a054c627SAkhil Goyal PROGRAM_SET_BSWAP(p);
529a054c627SAkhil Goyal if (ps)
530a054c627SAkhil Goyal PROGRAM_SET_36BIT_ADDR(p);
531a054c627SAkhil Goyal SHR_HDR(p, share, 1, SC);
532a054c627SAkhil Goyal
533a054c627SAkhil Goyal /* Do operation */
534a054c627SAkhil Goyal /* compute sequences */
535a054c627SAkhil Goyal if (opicv == ICV_CHECK_ENABLE)
536a054c627SAkhil Goyal MATHB(p, SEQINSZ, SUB, trunc_len, VSEQINSZ, 4, IMMED2);
537a054c627SAkhil Goyal else
538a054c627SAkhil Goyal MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
539a054c627SAkhil Goyal
540a054c627SAkhil Goyal ALG_OPERATION(p, authdata->algtype,
541a054c627SAkhil Goyal OP_ALG_AAI_HASH,
542a054c627SAkhil Goyal OP_ALG_AS_INITFINAL, opicv, dir);
543a054c627SAkhil Goyal SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
544a054c627SAkhil Goyal
545a054c627SAkhil Goyal if (opicv == ICV_CHECK_ENABLE)
546a054c627SAkhil Goyal SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
547a054c627SAkhil Goyal else
548a054c627SAkhil Goyal SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
549a054c627SAkhil Goyal
550a054c627SAkhil Goyal return PROGRAM_FINALIZE(p);
551a054c627SAkhil Goyal }
552a054c627SAkhil Goyal
553a054c627SAkhil Goyal /**
554c0ded849SHemant Agrawal * cnstr_shdsc_kasumi_f8 - KASUMI F8 (Confidentiality) as a shared descriptor
555c0ded849SHemant Agrawal * (ETSI "Document 1: f8 and f9 specification")
556c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
557c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
558c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
559c0ded849SHemant Agrawal * @cipherdata: pointer to block cipher transform definitions
560c0ded849SHemant Agrawal * @dir: cipher direction (DIR_ENC/DIR_DEC)
561c0ded849SHemant Agrawal * @count: count value (32 bits)
562c0ded849SHemant Agrawal * @bearer: bearer ID (5 bits)
563c0ded849SHemant Agrawal * @direction: direction (1 bit)
564c0ded849SHemant Agrawal *
565c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
566c0ded849SHemant Agrawal */
567c0ded849SHemant Agrawal static inline int
cnstr_shdsc_kasumi_f8(uint32_t * descbuf,bool ps,bool swap,struct alginfo * cipherdata,uint8_t dir)568c0ded849SHemant Agrawal cnstr_shdsc_kasumi_f8(uint32_t *descbuf, bool ps, bool swap,
569c0ded849SHemant Agrawal struct alginfo *cipherdata, uint8_t dir)
570c0ded849SHemant Agrawal {
571c0ded849SHemant Agrawal struct program prg;
572c0ded849SHemant Agrawal struct program *p = &prg;
573c0ded849SHemant Agrawal
574c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
575c0ded849SHemant Agrawal if (swap)
576c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
577c0ded849SHemant Agrawal if (ps)
578c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
579c0ded849SHemant Agrawal SHR_HDR(p, SHR_ALWAYS, 1, 0);
580c0ded849SHemant Agrawal
581c0ded849SHemant Agrawal KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
582c0ded849SHemant Agrawal cipherdata->keylen, INLINE_KEY(cipherdata));
583c0ded849SHemant Agrawal SEQLOAD(p, CONTEXT1, 0, 8, 0);
584c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
585c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQOUTSZ, 4, 0);
586c0ded849SHemant Agrawal ALG_OPERATION(p, OP_ALG_ALGSEL_KASUMI, OP_ALG_AAI_F8,
587c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, 0, dir);
588c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1);
589c0ded849SHemant Agrawal SEQFIFOSTORE(p, MSG, 0, 0, VLF);
590c0ded849SHemant Agrawal
591c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
592c0ded849SHemant Agrawal }
593c0ded849SHemant Agrawal
594c0ded849SHemant Agrawal /**
595c0ded849SHemant Agrawal * cnstr_shdsc_kasumi_f9 - KASUMI F9 (Integrity) as a shared descriptor
596c0ded849SHemant Agrawal * (ETSI "Document 1: f8 and f9 specification")
597c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
598c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
599c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
600c0ded849SHemant Agrawal * @authdata: pointer to authentication transform definitions
601c0ded849SHemant Agrawal * @chk_icv: check or generate ICV value
602c0ded849SHemant Agrawal * @authlen: size of digest
603c0ded849SHemant Agrawal *
604c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
605c0ded849SHemant Agrawal */
606c0ded849SHemant Agrawal static inline int
cnstr_shdsc_kasumi_f9(uint32_t * descbuf,bool ps,bool swap,struct alginfo * authdata,uint8_t chk_icv,uint32_t authlen)607c0ded849SHemant Agrawal cnstr_shdsc_kasumi_f9(uint32_t *descbuf, bool ps, bool swap,
608c0ded849SHemant Agrawal struct alginfo *authdata, uint8_t chk_icv,
609c0ded849SHemant Agrawal uint32_t authlen)
610c0ded849SHemant Agrawal {
611c0ded849SHemant Agrawal struct program prg;
612c0ded849SHemant Agrawal struct program *p = &prg;
613c0ded849SHemant Agrawal int dir = chk_icv ? DIR_DEC : DIR_ENC;
614c0ded849SHemant Agrawal
615c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
616c0ded849SHemant Agrawal if (swap)
617c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
618c0ded849SHemant Agrawal
619c0ded849SHemant Agrawal if (ps)
620c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
621c0ded849SHemant Agrawal
622c0ded849SHemant Agrawal SHR_HDR(p, SHR_ALWAYS, 1, 0);
623c0ded849SHemant Agrawal
624c0ded849SHemant Agrawal KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
625c0ded849SHemant Agrawal authdata->keylen, INLINE_KEY(authdata));
626c0ded849SHemant Agrawal
627c0ded849SHemant Agrawal SEQLOAD(p, CONTEXT2, 0, 12, 0);
628c0ded849SHemant Agrawal
629c0ded849SHemant Agrawal if (chk_icv == ICV_CHECK_ENABLE)
630c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, authlen, VSEQINSZ, 4, IMMED2);
631c0ded849SHemant Agrawal else
632c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
633c0ded849SHemant Agrawal
634c0ded849SHemant Agrawal ALG_OPERATION(p, OP_ALG_ALGSEL_KASUMI, OP_ALG_AAI_F9,
635c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, chk_icv, dir);
636c0ded849SHemant Agrawal
637c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG2, 0, VLF | CLASS2 | LAST2);
638c0ded849SHemant Agrawal
639c0ded849SHemant Agrawal if (chk_icv == ICV_CHECK_ENABLE)
640c0ded849SHemant Agrawal SEQFIFOLOAD(p, ICV2, authlen, LAST2);
641c0ded849SHemant Agrawal else
642c0ded849SHemant Agrawal /* Save lower half of MAC out into a 32-bit sequence */
643c0ded849SHemant Agrawal SEQSTORE(p, CONTEXT2, 0, authlen, 0);
644c0ded849SHemant Agrawal
645c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
646c0ded849SHemant Agrawal }
647c0ded849SHemant Agrawal
648c0ded849SHemant Agrawal /**
649c0ded849SHemant Agrawal * cnstr_shdsc_crc - CRC32 Accelerator (IEEE 802 CRC32 protocol mode)
650c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
651c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
652c0ded849SHemant Agrawal *
653c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
654c0ded849SHemant Agrawal */
655c0ded849SHemant Agrawal static inline int
cnstr_shdsc_crc(uint32_t * descbuf,bool swap)656c0ded849SHemant Agrawal cnstr_shdsc_crc(uint32_t *descbuf, bool swap)
657c0ded849SHemant Agrawal {
658c0ded849SHemant Agrawal struct program prg;
659c0ded849SHemant Agrawal struct program *p = &prg;
660c0ded849SHemant Agrawal
661c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
662c0ded849SHemant Agrawal if (swap)
663c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
664c0ded849SHemant Agrawal
665c0ded849SHemant Agrawal SHR_HDR(p, SHR_ALWAYS, 1, 0);
666c0ded849SHemant Agrawal
667c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
668c0ded849SHemant Agrawal ALG_OPERATION(p, OP_ALG_ALGSEL_CRC,
669c0ded849SHemant Agrawal OP_ALG_AAI_802 | OP_ALG_AAI_DOC,
670c0ded849SHemant Agrawal OP_ALG_AS_FINALIZE, 0, DIR_ENC);
671c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
672c0ded849SHemant Agrawal SEQSTORE(p, CONTEXT2, 0, 4, 0);
673c0ded849SHemant Agrawal
674c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
675c0ded849SHemant Agrawal }
676c0ded849SHemant Agrawal
677c0ded849SHemant Agrawal /**
678c0ded849SHemant Agrawal * cnstr_shdsc_gcm_encap - AES-GCM encap as a shared descriptor
679c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
680c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
681c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
682c0ded849SHemant Agrawal * @share: sharing type of shared descriptor
683c0ded849SHemant Agrawal * @cipherdata: pointer to block cipher transform definitions
684c0ded849SHemant Agrawal * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with
685c0ded849SHemant Agrawal * OP_ALG_AAI_GCM.
686c0ded849SHemant Agrawal * @ivlen: Initialization vector length
687c0ded849SHemant Agrawal * @icvsize: integrity check value (ICV) size (truncated or full)
688c0ded849SHemant Agrawal *
689c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
690c0ded849SHemant Agrawal */
691c0ded849SHemant Agrawal static inline int
cnstr_shdsc_gcm_encap(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct alginfo * cipherdata,uint32_t ivlen,uint32_t icvsize)692c0ded849SHemant Agrawal cnstr_shdsc_gcm_encap(uint32_t *descbuf, bool ps, bool swap,
693c0ded849SHemant Agrawal enum rta_share_type share,
694c0ded849SHemant Agrawal struct alginfo *cipherdata,
695c0ded849SHemant Agrawal uint32_t ivlen, uint32_t icvsize)
696c0ded849SHemant Agrawal {
697c0ded849SHemant Agrawal struct program prg;
698c0ded849SHemant Agrawal struct program *p = &prg;
699c0ded849SHemant Agrawal
700c0ded849SHemant Agrawal LABEL(keyjmp);
701c0ded849SHemant Agrawal LABEL(zeroassocjump2);
702c0ded849SHemant Agrawal LABEL(zeroassocjump1);
703c0ded849SHemant Agrawal LABEL(zeropayloadjump);
704c0ded849SHemant Agrawal REFERENCE(pkeyjmp);
705c0ded849SHemant Agrawal REFERENCE(pzeroassocjump2);
706c0ded849SHemant Agrawal REFERENCE(pzeroassocjump1);
707c0ded849SHemant Agrawal REFERENCE(pzeropayloadjump);
708c0ded849SHemant Agrawal
709c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
710c0ded849SHemant Agrawal
711c0ded849SHemant Agrawal if (swap)
712c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
713c0ded849SHemant Agrawal if (ps)
714c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
715c0ded849SHemant Agrawal
716c0ded849SHemant Agrawal SHR_HDR(p, share, 1, SC);
717c0ded849SHemant Agrawal
718c0ded849SHemant Agrawal pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SELF | SHRD);
719c0ded849SHemant Agrawal /* Insert Key */
720c0ded849SHemant Agrawal KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
721c0ded849SHemant Agrawal cipherdata->keylen, INLINE_KEY(cipherdata));
722c0ded849SHemant Agrawal
723c0ded849SHemant Agrawal SET_LABEL(p, keyjmp);
724c0ded849SHemant Agrawal
725c0ded849SHemant Agrawal /* class 1 operation */
726c0ded849SHemant Agrawal ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
727c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
728c0ded849SHemant Agrawal
729c0ded849SHemant Agrawal MATHB(p, DPOVRD, AND, 0x7fffffff, MATH3, 4, IMMED2);
730c0ded849SHemant Agrawal
731c0ded849SHemant Agrawal /* if assoclen + cryptlen is ZERO, skip to ICV write */
732c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, ivlen, VSEQOUTSZ, 4, IMMED2);
733c0ded849SHemant Agrawal pzeroassocjump2 = JUMP(p, zeroassocjump2, LOCAL_JUMP, ALL_TRUE, MATH_Z);
734c0ded849SHemant Agrawal
735c0ded849SHemant Agrawal SEQFIFOLOAD(p, IV1, ivlen, FLUSH1);
736c0ded849SHemant Agrawal
737c0ded849SHemant Agrawal /* if assoclen is ZERO, skip reading the assoc data */
738c0ded849SHemant Agrawal MATHB(p, ZERO, ADD, MATH3, VSEQINSZ, 4, 0);
739c0ded849SHemant Agrawal pzeroassocjump1 = JUMP(p, zeroassocjump1, LOCAL_JUMP, ALL_TRUE, MATH_Z);
740c0ded849SHemant Agrawal
741c0ded849SHemant Agrawal /* cryptlen = seqinlen - assoclen */
742c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
743c0ded849SHemant Agrawal
744c0ded849SHemant Agrawal /* if cryptlen is ZERO jump to zero-payload commands */
745c0ded849SHemant Agrawal pzeropayloadjump = JUMP(p, zeropayloadjump, LOCAL_JUMP, ALL_TRUE,
746c0ded849SHemant Agrawal MATH_Z);
747c0ded849SHemant Agrawal
748c0ded849SHemant Agrawal /* read assoc data */
749c0ded849SHemant Agrawal SEQFIFOLOAD(p, AAD1, 0, CLASS1 | VLF | FLUSH1);
750c0ded849SHemant Agrawal SET_LABEL(p, zeroassocjump1);
751c0ded849SHemant Agrawal
752c0ded849SHemant Agrawal MATHB(p, SEQINSZ, SUB, MATH0, VSEQINSZ, 4, 0);
753c0ded849SHemant Agrawal
754c0ded849SHemant Agrawal /* write encrypted data */
755c0ded849SHemant Agrawal SEQFIFOSTORE(p, MSG, 0, 0, VLF);
756c0ded849SHemant Agrawal
757c0ded849SHemant Agrawal /* read payload data */
758c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG1, 0, CLASS1 | VLF | LAST1);
759c0ded849SHemant Agrawal
760c0ded849SHemant Agrawal /* jump the zero-payload commands */
761c0ded849SHemant Agrawal JUMP(p, 4, LOCAL_JUMP, ALL_TRUE, 0);
762c0ded849SHemant Agrawal
763c0ded849SHemant Agrawal /* zero-payload commands */
764c0ded849SHemant Agrawal SET_LABEL(p, zeropayloadjump);
765c0ded849SHemant Agrawal
766c0ded849SHemant Agrawal /* read assoc data */
767c0ded849SHemant Agrawal SEQFIFOLOAD(p, AAD1, 0, CLASS1 | VLF | LAST1);
768c0ded849SHemant Agrawal
769c0ded849SHemant Agrawal JUMP(p, 2, LOCAL_JUMP, ALL_TRUE, 0);
770c0ded849SHemant Agrawal
771c0ded849SHemant Agrawal /* There is no input data */
772c0ded849SHemant Agrawal SET_LABEL(p, zeroassocjump2);
773c0ded849SHemant Agrawal
774c0ded849SHemant Agrawal SEQFIFOLOAD(p, IV1, ivlen, FLUSH1 | LAST1);
775c0ded849SHemant Agrawal
776c0ded849SHemant Agrawal /* write ICV */
777c0ded849SHemant Agrawal SEQSTORE(p, CONTEXT1, 0, icvsize, 0);
778c0ded849SHemant Agrawal
779c0ded849SHemant Agrawal PATCH_JUMP(p, pkeyjmp, keyjmp);
780c0ded849SHemant Agrawal PATCH_JUMP(p, pzeroassocjump2, zeroassocjump2);
781c0ded849SHemant Agrawal PATCH_JUMP(p, pzeroassocjump1, zeroassocjump1);
782c0ded849SHemant Agrawal PATCH_JUMP(p, pzeropayloadjump, zeropayloadjump);
783c0ded849SHemant Agrawal
784c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
785c0ded849SHemant Agrawal }
786c0ded849SHemant Agrawal
787c0ded849SHemant Agrawal /**
788c0ded849SHemant Agrawal * cnstr_shdsc_gcm_decap - AES-GCM decap as a shared descriptor
789c0ded849SHemant Agrawal * @descbuf: pointer to descriptor-under-construction buffer
790c0ded849SHemant Agrawal * @ps: if 36/40bit addressing is desired, this parameter must be true
791c0ded849SHemant Agrawal * @swap: must be true when core endianness doesn't match SEC endianness
792c0ded849SHemant Agrawal * @share: sharing type of shared descriptor
793c0ded849SHemant Agrawal * @cipherdata: pointer to block cipher transform definitions
794c0ded849SHemant Agrawal * Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with
795c0ded849SHemant Agrawal * OP_ALG_AAI_GCM.
796c0ded849SHemant Agrawal * @icvsize: integrity check value (ICV) size (truncated or full)
797c0ded849SHemant Agrawal *
798c0ded849SHemant Agrawal * Return: size of descriptor written in words or negative number on error
799c0ded849SHemant Agrawal */
800c0ded849SHemant Agrawal static inline int
cnstr_shdsc_gcm_decap(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct alginfo * cipherdata,uint32_t ivlen,uint32_t icvsize)801c0ded849SHemant Agrawal cnstr_shdsc_gcm_decap(uint32_t *descbuf, bool ps, bool swap,
802c0ded849SHemant Agrawal enum rta_share_type share,
803c0ded849SHemant Agrawal struct alginfo *cipherdata,
804c0ded849SHemant Agrawal uint32_t ivlen, uint32_t icvsize)
805c0ded849SHemant Agrawal {
806c0ded849SHemant Agrawal struct program prg;
807c0ded849SHemant Agrawal struct program *p = &prg;
808c0ded849SHemant Agrawal
809c0ded849SHemant Agrawal LABEL(keyjmp);
810c0ded849SHemant Agrawal LABEL(zeroassocjump1);
811c0ded849SHemant Agrawal LABEL(zeropayloadjump);
812c0ded849SHemant Agrawal REFERENCE(pkeyjmp);
813c0ded849SHemant Agrawal REFERENCE(pzeroassocjump1);
814c0ded849SHemant Agrawal REFERENCE(pzeropayloadjump);
815c0ded849SHemant Agrawal
816c0ded849SHemant Agrawal PROGRAM_CNTXT_INIT(p, descbuf, 0);
817c0ded849SHemant Agrawal
818c0ded849SHemant Agrawal if (swap)
819c0ded849SHemant Agrawal PROGRAM_SET_BSWAP(p);
820c0ded849SHemant Agrawal if (ps)
821c0ded849SHemant Agrawal PROGRAM_SET_36BIT_ADDR(p);
822c0ded849SHemant Agrawal
823c0ded849SHemant Agrawal SHR_HDR(p, share, 1, SC);
824c0ded849SHemant Agrawal
825c0ded849SHemant Agrawal pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SELF | SHRD);
826c0ded849SHemant Agrawal /* Insert Key */
827c0ded849SHemant Agrawal KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
828c0ded849SHemant Agrawal cipherdata->keylen, INLINE_KEY(cipherdata));
829c0ded849SHemant Agrawal
830c0ded849SHemant Agrawal SET_LABEL(p, keyjmp);
831c0ded849SHemant Agrawal
832c0ded849SHemant Agrawal /* class 1 operation */
833c0ded849SHemant Agrawal ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
834c0ded849SHemant Agrawal OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
835c0ded849SHemant Agrawal
836c0ded849SHemant Agrawal MATHB(p, DPOVRD, AND, 0x7fffffff, MATH3, 4, IMMED2);
837c0ded849SHemant Agrawal SEQFIFOLOAD(p, IV1, ivlen, FLUSH1);
838c0ded849SHemant Agrawal
839c0ded849SHemant Agrawal /* if assoclen is ZERO, skip reading the assoc data */
840c0ded849SHemant Agrawal MATHB(p, ZERO, ADD, MATH3, VSEQINSZ, 4, 0);
841c0ded849SHemant Agrawal pzeroassocjump1 = JUMP(p, zeroassocjump1, LOCAL_JUMP, ALL_TRUE, MATH_Z);
842c0ded849SHemant Agrawal
843c0ded849SHemant Agrawal /* read assoc data */
844c0ded849SHemant Agrawal SEQFIFOLOAD(p, AAD1, 0, CLASS1 | VLF | FLUSH1);
845c0ded849SHemant Agrawal
846c0ded849SHemant Agrawal SET_LABEL(p, zeroassocjump1);
847c0ded849SHemant Agrawal
848c0ded849SHemant Agrawal /* cryptlen = seqoutlen - assoclen */
849c0ded849SHemant Agrawal MATHB(p, SEQOUTSZ, SUB, MATH0, VSEQINSZ, 4, 0);
850c0ded849SHemant Agrawal
851c0ded849SHemant Agrawal /* jump to zero-payload command if cryptlen is zero */
852c0ded849SHemant Agrawal pzeropayloadjump = JUMP(p, zeropayloadjump, LOCAL_JUMP, ALL_TRUE,
853c0ded849SHemant Agrawal MATH_Z);
854c0ded849SHemant Agrawal
855c0ded849SHemant Agrawal MATHB(p, SEQOUTSZ, SUB, MATH0, VSEQOUTSZ, 4, 0);
856c0ded849SHemant Agrawal
857c0ded849SHemant Agrawal /* store encrypted data */
858c0ded849SHemant Agrawal SEQFIFOSTORE(p, MSG, 0, 0, VLF);
859c0ded849SHemant Agrawal
860c0ded849SHemant Agrawal /* read payload data */
861c0ded849SHemant Agrawal SEQFIFOLOAD(p, MSG1, 0, CLASS1 | VLF | FLUSH1);
862c0ded849SHemant Agrawal
863c0ded849SHemant Agrawal /* zero-payload command */
864c0ded849SHemant Agrawal SET_LABEL(p, zeropayloadjump);
865c0ded849SHemant Agrawal
866c0ded849SHemant Agrawal /* read ICV */
867c0ded849SHemant Agrawal SEQFIFOLOAD(p, ICV1, icvsize, CLASS1 | LAST1);
868c0ded849SHemant Agrawal
869c0ded849SHemant Agrawal PATCH_JUMP(p, pkeyjmp, keyjmp);
870c0ded849SHemant Agrawal PATCH_JUMP(p, pzeroassocjump1, zeroassocjump1);
871c0ded849SHemant Agrawal PATCH_JUMP(p, pzeropayloadjump, zeropayloadjump);
872c0ded849SHemant Agrawal
873c0ded849SHemant Agrawal return PROGRAM_FINALIZE(p);
874c0ded849SHemant Agrawal }
875c0ded849SHemant Agrawal
876caf84d61SAkhil Goyal /**
87783087a92SHemant Agrawal * cnstr_shdsc_aes_mac - AES_XCBC_MAC, CMAC cases
878caf84d61SAkhil Goyal * @descbuf: pointer to descriptor-under-construction buffer
879caf84d61SAkhil Goyal * @ps: if 36/40bit addressing is desired, this parameter must be true
880caf84d61SAkhil Goyal * @swap: must be true when core endianness doesn't match SEC endianness
881caf84d61SAkhil Goyal * @share: sharing type of shared descriptor
882caf84d61SAkhil Goyal * @authdata: pointer to authentication transform definitions;
883caf84d61SAkhil Goyal * message digest algorithm: OP_ALG_ALGSEL_AES.
884caf84d61SAkhil Goyal * @do_icv: 0 if ICV checking is not desired, any other value if ICV checking
885caf84d61SAkhil Goyal * is needed for all the packets processed by this shared descriptor
886caf84d61SAkhil Goyal * @trunc_len: Length of the truncated ICV to be written in the output buffer,
887caf84d61SAkhil Goyal * 0 if no truncation is needed
888caf84d61SAkhil Goyal *
889caf84d61SAkhil Goyal * Note: There's no support for keys longer than the block size of the
890caf84d61SAkhil Goyal * underlying hash function, according to the selected algorithm.
891caf84d61SAkhil Goyal *
892caf84d61SAkhil Goyal * Return: size of descriptor written in words or negative number on error
893caf84d61SAkhil Goyal */
894caf84d61SAkhil Goyal static inline int
cnstr_shdsc_aes_mac(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct alginfo * authdata,uint8_t do_icv,uint8_t trunc_len)89583087a92SHemant Agrawal cnstr_shdsc_aes_mac(uint32_t *descbuf, bool ps, bool swap,
896caf84d61SAkhil Goyal enum rta_share_type share,
897caf84d61SAkhil Goyal struct alginfo *authdata, uint8_t do_icv,
898caf84d61SAkhil Goyal uint8_t trunc_len)
899caf84d61SAkhil Goyal {
900caf84d61SAkhil Goyal struct program prg;
901caf84d61SAkhil Goyal struct program *p = &prg;
902caf84d61SAkhil Goyal uint8_t opicv, dir;
903caf84d61SAkhil Goyal
904caf84d61SAkhil Goyal opicv = do_icv ? ICV_CHECK_ENABLE : ICV_CHECK_DISABLE;
905caf84d61SAkhil Goyal dir = do_icv ? DIR_DEC : DIR_ENC;
906caf84d61SAkhil Goyal
907caf84d61SAkhil Goyal PROGRAM_CNTXT_INIT(p, descbuf, 0);
908caf84d61SAkhil Goyal if (swap)
909caf84d61SAkhil Goyal PROGRAM_SET_BSWAP(p);
910caf84d61SAkhil Goyal if (ps)
911caf84d61SAkhil Goyal PROGRAM_SET_36BIT_ADDR(p);
912caf84d61SAkhil Goyal SHR_HDR(p, share, 1, SC);
913caf84d61SAkhil Goyal
914caf84d61SAkhil Goyal KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
915caf84d61SAkhil Goyal INLINE_KEY(authdata));
916caf84d61SAkhil Goyal
917caf84d61SAkhil Goyal /* compute sequences */
918caf84d61SAkhil Goyal if (opicv == ICV_CHECK_ENABLE)
919caf84d61SAkhil Goyal MATHB(p, SEQINSZ, SUB, trunc_len, VSEQINSZ, 4, IMMED2);
920caf84d61SAkhil Goyal else
921caf84d61SAkhil Goyal MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
922caf84d61SAkhil Goyal
923caf84d61SAkhil Goyal /* Do operation */
92483087a92SHemant Agrawal ALG_OPERATION_NP(p, authdata->algtype, authdata->algmode,
925caf84d61SAkhil Goyal OP_ALG_AS_INITFINAL, opicv, dir);
926caf84d61SAkhil Goyal
927caf84d61SAkhil Goyal /* Do load (variable length) */
928caf84d61SAkhil Goyal SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
929caf84d61SAkhil Goyal
930caf84d61SAkhil Goyal if (opicv == ICV_CHECK_ENABLE) {
931caf84d61SAkhil Goyal LOAD(p, trunc_len, ICV2SZ, 0, 4, IMMED);
932caf84d61SAkhil Goyal SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
933caf84d61SAkhil Goyal } else
934caf84d61SAkhil Goyal SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
935caf84d61SAkhil Goyal
936caf84d61SAkhil Goyal return PROGRAM_FINALIZE(p);
937caf84d61SAkhil Goyal }
938caf84d61SAkhil Goyal
939c0ded849SHemant Agrawal #endif /* __DESC_ALGO_H__ */
940