1233541Sjchandra/*-
2233541Sjchandra * Copyright (c) 2003-2012 Broadcom Corporation
3233541Sjchandra * All Rights Reserved
4233541Sjchandra *
5233541Sjchandra * Redistribution and use in source and binary forms, with or without
6233541Sjchandra * modification, are permitted provided that the following conditions
7233541Sjchandra * are met:
8233541Sjchandra *
9233541Sjchandra * 1. Redistributions of source code must retain the above copyright
10233541Sjchandra *    notice, this list of conditions and the following disclaimer.
11233541Sjchandra * 2. Redistributions in binary form must reproduce the above copyright
12233541Sjchandra *    notice, this list of conditions and the following disclaimer in
13233541Sjchandra *    the documentation and/or other materials provided with the
14233541Sjchandra *    distribution.
15279387Sjchandra *
16233541Sjchandra * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
17233541Sjchandra * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18233541Sjchandra * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19233541Sjchandra * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
20233541Sjchandra * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21233541Sjchandra * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22233541Sjchandra * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23233541Sjchandra * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24233541Sjchandra * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25233541Sjchandra * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26233541Sjchandra * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27233541Sjchandra *
28233541Sjchandra * $FreeBSD$
29233541Sjchandra */
30233541Sjchandra
31233541Sjchandra#ifndef _NLM_HAL_CRYPTO_H_
32233541Sjchandra#define _NLM_HAL_CRYPTO_H_
33233541Sjchandra
34233541Sjchandra#define	SAE_CFG_REG		0x00
35233541Sjchandra#define SAE_ENG_SEL_0		0x01
36233541Sjchandra#define SAE_ENG_SEL_1		0x02
37233541Sjchandra#define SAE_ENG_SEL_2		0x03
38233541Sjchandra#define SAE_ENG_SEL_3		0x04
39233541Sjchandra#define SAE_ENG_SEL_4		0x05
40233541Sjchandra#define SAE_ENG_SEL_5		0x06
41233541Sjchandra#define SAE_ENG_SEL_6		0x07
42233541Sjchandra#define SAE_ENG_SEL_7		0x08
43233541Sjchandra
44233541Sjchandra#define	RSA_CFG_REG		0x00
45233541Sjchandra#define RSA_ENG_SEL_0		0x01
46233541Sjchandra#define RSA_ENG_SEL_1		0x02
47233541Sjchandra#define RSA_ENG_SEL_2		0x03
48233541Sjchandra
49233541Sjchandra#define nlm_read_sec_reg(b, r)		nlm_read_reg(b, r)
50233541Sjchandra#define nlm_write_sec_reg(b, r, v)	nlm_write_reg(b, r, v)
51233541Sjchandra#define nlm_get_sec_pcibase(node)	nlm_pcicfg_base(XLP_IO_SEC_OFFSET(node))
52233541Sjchandra#define nlm_get_sec_regbase(node)        \
53233541Sjchandra                        (nlm_get_sec_pcibase(node) + XLP_IO_PCI_HDRSZ)
54233541Sjchandra
55233541Sjchandra#define nlm_read_rsa_reg(b, r)		nlm_read_reg(b, r)
56233541Sjchandra#define nlm_write_rsa_reg(b, r, v)	nlm_write_reg(b, r, v)
57233541Sjchandra#define nlm_get_rsa_pcibase(node)	nlm_pcicfg_base(XLP_IO_RSA_OFFSET(node))
58233541Sjchandra#define nlm_get_rsa_regbase(node)        \
59233541Sjchandra                        (nlm_get_rsa_pcibase(node) + XLP_IO_PCI_HDRSZ)
60233541Sjchandra
61233541Sjchandra#define nlm_pcibase_sec(node)     nlm_pcicfg_base(XLP_IO_SEC_OFFSET(node))
62233541Sjchandra#define nlm_qidstart_sec(node)    nlm_qidstart_kseg(nlm_pcibase_sec(node))
63233541Sjchandra#define nlm_qnum_sec(node)        nlm_qnum_kseg(nlm_pcibase_sec(node))
64233541Sjchandra
65233541Sjchandra/*
66233541Sjchandra * Since buffer allocation for crypto at kernel is done as malloc, each
67233541Sjchandra * segment size is given as page size which is 4K by default
68233541Sjchandra */
69279387Sjchandra#define NLM_CRYPTO_MAX_SEG_LEN	PAGE_SIZE
70233541Sjchandra
71233541Sjchandra#define MAX_KEY_LEN_IN_DW		20
72233541Sjchandra
73233541Sjchandra#define left_shift64(x, bitshift, numofbits)			\
74233541Sjchandra    ((uint64_t)(x) << (bitshift))
75233541Sjchandra
76233541Sjchandra#define left_shift64_mask(x, bitshift, numofbits)			\
77233541Sjchandra    (((uint64_t)(x) & ((1ULL << (numofbits)) - 1)) << (bitshift))
78233541Sjchandra
79233541Sjchandra/**
80233541Sjchandra* @brief cipher algorithms
81233541Sjchandra* @ingroup crypto
82233541Sjchandra*/
83233541Sjchandraenum nlm_cipher_algo {
84233541Sjchandra	NLM_CIPHER_BYPASS = 0,
85233541Sjchandra	NLM_CIPHER_DES = 1,
86279387Sjchandra	NLM_CIPHER_3DES = 2,
87233541Sjchandra	NLM_CIPHER_AES128 = 3,
88233541Sjchandra	NLM_CIPHER_AES192 = 4,
89279387Sjchandra	NLM_CIPHER_AES256 = 5,
90279387Sjchandra	NLM_CIPHER_ARC4 = 6,
91233541Sjchandra	NLM_CIPHER_KASUMI_F8 = 7,
92279387Sjchandra	NLM_CIPHER_SNOW3G_F8 = 8,
93279387Sjchandra	NLM_CIPHER_CAMELLIA128 = 9,
94279387Sjchandra	NLM_CIPHER_CAMELLIA192 = 0xA,
95279387Sjchandra	NLM_CIPHER_CAMELLIA256 = 0xB,
96233541Sjchandra	NLM_CIPHER_MAX = 0xC,
97233541Sjchandra};
98233541Sjchandra
99233541Sjchandra/**
100233541Sjchandra* @brief cipher modes
101233541Sjchandra* @ingroup crypto
102233541Sjchandra*/
103233541Sjchandraenum nlm_cipher_mode {
104233541Sjchandra	NLM_CIPHER_MODE_ECB = 0,
105233541Sjchandra	NLM_CIPHER_MODE_CBC = 1,
106233541Sjchandra	NLM_CIPHER_MODE_CFB = 2,
107233541Sjchandra	NLM_CIPHER_MODE_OFB = 3,
108233541Sjchandra	NLM_CIPHER_MODE_CTR = 4,
109233541Sjchandra	NLM_CIPHER_MODE_AES_F8 = 5,
110233541Sjchandra	NLM_CIPHER_MODE_GCM = 6,
111233541Sjchandra	NLM_CIPHER_MODE_CCM = 7,
112233541Sjchandra	NLM_CIPHER_MODE_UNDEFINED1 = 8,
113233541Sjchandra	NLM_CIPHER_MODE_UNDEFINED2 = 9,
114233541Sjchandra	NLM_CIPHER_MODE_LRW = 0xA,
115233541Sjchandra	NLM_CIPHER_MODE_XTS = 0xB,
116233541Sjchandra	NLM_CIPHER_MODE_MAX = 0xC,
117233541Sjchandra};
118233541Sjchandra
119233541Sjchandra/**
120233541Sjchandra* @brief hash algorithms
121233541Sjchandra* @ingroup crypto
122233541Sjchandra*/
123233541Sjchandraenum nlm_hash_algo {
124233541Sjchandra	NLM_HASH_BYPASS = 0,
125233541Sjchandra	NLM_HASH_MD5 = 1,
126233541Sjchandra	NLM_HASH_SHA = 2,
127233541Sjchandra	NLM_HASH_UNDEFINED = 3,
128233541Sjchandra	NLM_HASH_AES128 = 4,
129233541Sjchandra	NLM_HASH_AES192 = 5,
130233541Sjchandra	NLM_HASH_AES256 = 6,
131233541Sjchandra	NLM_HASH_KASUMI_F9 = 7,
132233541Sjchandra	NLM_HASH_SNOW3G_F9 = 8,
133233541Sjchandra	NLM_HASH_CAMELLIA128 = 9,
134233541Sjchandra	NLM_HASH_CAMELLIA192 = 0xA,
135233541Sjchandra	NLM_HASH_CAMELLIA256 = 0xB,
136233541Sjchandra	NLM_HASH_GHASH = 0xC,
137233541Sjchandra	NLM_HASH_MAX = 0xD
138233541Sjchandra};
139233541Sjchandra
140233541Sjchandra/**
141233541Sjchandra* @brief hash modes
142233541Sjchandra* @ingroup crypto
143233541Sjchandra*/
144233541Sjchandraenum nlm_hash_mode {
145233541Sjchandra	NLM_HASH_MODE_SHA1 = 0,	/* Only SHA */
146233541Sjchandra	NLM_HASH_MODE_SHA224 = 1,	/* Only SHA */
147233541Sjchandra	NLM_HASH_MODE_SHA256 = 2,	/* Only SHA */
148233541Sjchandra	NLM_HASH_MODE_SHA384 = 3,	/* Only SHA */
149233541Sjchandra	NLM_HASH_MODE_SHA512 = 4,	/* Only SHA */
150233541Sjchandra	NLM_HASH_MODE_CMAC = 5,	/* AES and Camellia */
151233541Sjchandra	NLM_HASH_MODE_XCBC = 6,	/* AES and Camellia */
152233541Sjchandra	NLM_HASH_MODE_CBC_MAC = 7,	/* AES and Camellia */
153233541Sjchandra	NLM_HASH_MODE_CCM = 8,	/* AES */
154233541Sjchandra	NLM_HASH_MODE_GCM = 9,	/* AES */
155233541Sjchandra	NLM_HASH_MODE_MAX = 0xA,
156279387Sjchandra};
157233541Sjchandra
158233541Sjchandra/**
159233541Sjchandra* @brief crypto control descriptor, should be cache aligned
160233541Sjchandra* @ingroup crypto
161233541Sjchandra*/
162233541Sjchandrastruct nlm_crypto_pkt_ctrl {
163233541Sjchandra	uint64_t desc0;
164233541Sjchandra	/* combination of cipher and hash keys */
165233541Sjchandra	uint64_t key[MAX_KEY_LEN_IN_DW];
166279387Sjchandra	uint32_t cipherkeylen;
167279387Sjchandra	uint32_t hashkeylen;
168233541Sjchandra	uint32_t taglen;
169233541Sjchandra};
170233541Sjchandra
171233541Sjchandra/**
172279387Sjchandra* @brief crypto packet descriptor, should be cache aligned
173233541Sjchandra* @ingroup crypto
174233541Sjchandra*/
175233541Sjchandrastruct nlm_crypto_pkt_param {
176233541Sjchandra	uint64_t desc0;
177279387Sjchandra	uint64_t desc1;
178233541Sjchandra	uint64_t desc2;
179233541Sjchandra	uint64_t desc3;
180233541Sjchandra	uint64_t segment[1][2];
181233541Sjchandra};
182233541Sjchandra
183233541Sjchandrastatic __inline__ uint64_t
184279387Sjchandranlm_crypto_form_rsa_ecc_fmn_entry0(unsigned int l3alloc, unsigned int type,
185233541Sjchandra    unsigned int func, uint64_t srcaddr)
186233541Sjchandra{
187279387Sjchandra	return (left_shift64(l3alloc, 61, 1) |
188233541Sjchandra	    left_shift64(type, 46, 7) |
189233541Sjchandra	    left_shift64(func, 40, 6) |
190233541Sjchandra	    left_shift64(srcaddr, 0, 40));
191233541Sjchandra}
192233541Sjchandra
193233541Sjchandrastatic __inline__ uint64_t
194233541Sjchandranlm_crypto_form_rsa_ecc_fmn_entry1(unsigned int dstclobber,
195233541Sjchandra    unsigned int l3alloc, unsigned int fbvc, uint64_t dstaddr)
196233541Sjchandra{
197233541Sjchandra	return (left_shift64(dstclobber, 62, 1) |
198233541Sjchandra	    left_shift64(l3alloc, 61, 1) |
199233541Sjchandra	    left_shift64(fbvc, 40, 12) |
200233541Sjchandra	    left_shift64(dstaddr, 0, 40));
201233541Sjchandra}
202233541Sjchandra
203233541Sjchandra/**
204233541Sjchandra* @brief Generate cypto control descriptor
205233541Sjchandra* @ingroup crypto
206279387Sjchandra* hmac : 1 for hash with hmac
207233541Sjchandra* hashalg, see hash_alg enums
208233541Sjchandra* hashmode, see hash_mode enums
209233541Sjchandra* cipherhalg, see  cipher_alg enums
210233541Sjchandra* ciphermode, see  cipher_mode enums
211279387Sjchandra* arc4_cipherkeylen : length of arc4 cipher key, 0 is interpreted as 32
212279387Sjchandra* arc4_keyinit :
213279387Sjchandra* cfbmask : cipher text for feedback,
214233541Sjchandra*           0(1 bit), 1(2 bits), 2(4 bits), 3(8 bits), 4(16bits), 5(32 bits),
215233541Sjchandra*           6(64 bits), 7(128 bits)
216233541Sjchandra*/
217233541Sjchandrastatic __inline__ uint64_t
218233541Sjchandranlm_crypto_form_pkt_ctrl_desc(unsigned int hmac, unsigned int hashalg,
219233541Sjchandra    unsigned int hashmode, unsigned int cipheralg, unsigned int ciphermode,
220233541Sjchandra    unsigned int arc4_cipherkeylen, unsigned int arc4_keyinit,
221233541Sjchandra    unsigned int cfbmask)
222233541Sjchandra{
223279387Sjchandra	return (left_shift64(hmac, 61, 1) |
224279387Sjchandra	    left_shift64(hashalg, 52, 8) |
225279387Sjchandra	    left_shift64(hashmode, 43, 8) |
226279387Sjchandra	    left_shift64(cipheralg, 34, 8) |
227279387Sjchandra	    left_shift64(ciphermode, 25, 8) |
228279387Sjchandra	    left_shift64(arc4_cipherkeylen, 18, 5) |
229279387Sjchandra	    left_shift64(arc4_keyinit, 17, 1) |
230233541Sjchandra	    left_shift64(cfbmask, 0, 3));
231233541Sjchandra}
232233541Sjchandra/**
233233541Sjchandra* @brief Generate cypto packet descriptor 0
234233541Sjchandra* @ingroup crypto
235233541Sjchandra* tls : 1 (tls enabled) 0(tls disabled)
236233541Sjchandra* hash_source : 1 (encrypted data is sent to the auth engine)
237233541Sjchandra*               0 (plain data is sent to the auth engine)
238233541Sjchandra* hashout_l3alloc : 1 (auth output is transited through l3 cache)
239233541Sjchandra* encrypt : 1 (for encrypt) 0 (for decrypt)
240233541Sjchandra* ivlen : iv length in bytes
241233541Sjchandra* hashdst_addr : hash out physical address, byte aligned
242233541Sjchandra*/
243233541Sjchandrastatic __inline__ uint64_t
244233541Sjchandranlm_crypto_form_pkt_desc0(unsigned int tls, unsigned int hash_source,
245233541Sjchandra    unsigned int hashout_l3alloc, unsigned int encrypt, unsigned int ivlen,
246233541Sjchandra    uint64_t hashdst_addr)
247233541Sjchandra{
248233541Sjchandra	return (left_shift64(tls, 63, 1) |
249233541Sjchandra	    left_shift64(hash_source, 62, 1) |
250233541Sjchandra	    left_shift64(hashout_l3alloc, 60, 1) |
251233541Sjchandra	    left_shift64(encrypt, 59, 1) |
252233541Sjchandra	    left_shift64_mask((ivlen - 1), 41, 16) |
253233541Sjchandra	    left_shift64(hashdst_addr, 0, 40));
254233541Sjchandra}
255233541Sjchandra
256233541Sjchandra/**
257233541Sjchandra* @brief Generate cypto packet descriptor 1
258233541Sjchandra* @ingroup crypto
259233541Sjchandra* cipherlen : cipher length in bytes
260233541Sjchandra* hashlen : hash length in bytes
261233541Sjchandra*/
262233541Sjchandrastatic __inline__ uint64_t
263233541Sjchandranlm_crypto_form_pkt_desc1(unsigned int cipherlen, unsigned int hashlen)
264233541Sjchandra{
265233541Sjchandra	return (left_shift64_mask((cipherlen - 1), 32, 32) |
266233541Sjchandra	    left_shift64_mask((hashlen - 1), 0, 32));
267279387Sjchandra}
268233541Sjchandra
269233541Sjchandra/**
270233541Sjchandra* @brief Generate cypto packet descriptor 2
271233541Sjchandra* @ingroup crypto
272233541Sjchandra* ivoff : iv offset, offset from start of src data addr
273233541Sjchandra* ciperbit_cnt : number of valid bits in the last input byte to the cipher,
274233541Sjchandra*                0 (8 bits), 1 (1 bit)..7 (7 bits)
275233541Sjchandra* cipheroff : cipher offset, offset from start of src data addr
276233541Sjchandra* hashbit_cnt : number of valid bits in the last input byte to the auth
277233541Sjchandra*              0 (8 bits), 1 (1 bit)..7 (7 bits)
278233541Sjchandra* hashclobber : 1 (hash output will be written as multiples of cachelines, no
279233541Sjchandra*              read modify write)
280233541Sjchandra* hashoff : hash offset, offset from start of src data addr
281233541Sjchandra*/
282233541Sjchandra
283233541Sjchandrastatic __inline__ uint64_t
284233541Sjchandranlm_crypto_form_pkt_desc2(unsigned int ivoff, unsigned int cipherbit_cnt,
285233541Sjchandra    unsigned int cipheroff, unsigned int hashbit_cnt, unsigned int hashclobber,
286233541Sjchandra    unsigned int hashoff)
287233541Sjchandra{
288233541Sjchandra	return (left_shift64(ivoff , 45, 16) |
289233541Sjchandra	    left_shift64(cipherbit_cnt, 42, 3) |
290233541Sjchandra	    left_shift64(cipheroff, 22, 16) |
291233541Sjchandra	    left_shift64(hashbit_cnt, 19, 3) |
292233541Sjchandra	    left_shift64(hashclobber, 18, 1) |
293233541Sjchandra	    left_shift64(hashoff, 0, 16));
294233541Sjchandra}
295233541Sjchandra
296233541Sjchandra/**
297233541Sjchandra* @brief Generate cypto packet descriptor 3
298233541Sjchandra* @ingroup crypto
299233541Sjchandra* designer_vc : designer freeback fmn destination id
300233541Sjchandra* taglen : length in bits of the tag generated by the auth engine
301233541Sjchandra*          md5 (128 bits), sha1 (160), sha224 (224), sha384 (384),
302233541Sjchandra*          sha512 (512), Kasumi (32), snow3g (32), gcm (128)
303279387Sjchandra* hmacpad : 1 if hmac padding is already done
304233541Sjchandra*/
305233541Sjchandrastatic  __inline__ uint64_t
306233541Sjchandranlm_crypto_form_pkt_desc3(unsigned int designer_vc, unsigned int taglen,
307233541Sjchandra    unsigned int arc4_state_save_l3, unsigned int arc4_save_state,
308233541Sjchandra    unsigned int hmacpad)
309233541Sjchandra{
310233541Sjchandra	return (left_shift64(designer_vc, 48, 16) |
311233541Sjchandra	    left_shift64(taglen, 11, 16) |
312233541Sjchandra	    left_shift64(arc4_state_save_l3, 8, 1) |
313233541Sjchandra	    left_shift64(arc4_save_state, 6, 1) |
314233541Sjchandra	    left_shift64(hmacpad, 5, 1));
315233541Sjchandra}
316233541Sjchandra
317233541Sjchandra/**
318233541Sjchandra* @brief Generate cypto packet descriptor 4
319233541Sjchandra* @ingroup crypto
320233541Sjchandra* srcfraglen : length of the source fragment(header + data + tail) in bytes
321233541Sjchandra* srcfragaddr : physical address of the srouce fragment
322233541Sjchandra*/
323233541Sjchandrastatic __inline__ uint64_t
324233541Sjchandranlm_crypto_form_pkt_desc4(uint64_t srcfraglen,
325233541Sjchandra    unsigned int srcfragaddr )
326233541Sjchandra{
327233541Sjchandra	return (left_shift64_mask((srcfraglen - 1), 48, 16) |
328233541Sjchandra	    left_shift64(srcfragaddr, 0, 40));
329233541Sjchandra}
330233541Sjchandra
331233541Sjchandra/**
332233541Sjchandra* @brief Generate cypto packet descriptor 5
333233541Sjchandra* @ingroup crypto
334233541Sjchandra* dstfraglen : length of the dst fragment(header + data + tail) in bytes
335233541Sjchandra* chipherout_l3alloc : 1(cipher output is transited through l3 cache)
336233541Sjchandra* cipherclobber : 1 (cipher output will be written as multiples of cachelines,
337233541Sjchandra*                 no read modify write)
338233541Sjchandra* chiperdst_addr : physical address of the cipher destination address
339233541Sjchandra*/
340233541Sjchandrastatic __inline__ uint64_t
341233541Sjchandranlm_crypto_form_pkt_desc5(unsigned int dstfraglen,
342233541Sjchandra    unsigned int cipherout_l3alloc, unsigned int cipherclobber,
343233541Sjchandra    uint64_t cipherdst_addr)
344233541Sjchandra
345233541Sjchandra{
346233541Sjchandra	return (left_shift64_mask((dstfraglen - 1), 48, 16) |
347233541Sjchandra	    left_shift64(cipherout_l3alloc, 46, 1) |
348233541Sjchandra	    left_shift64(cipherclobber, 41, 1) |
349233541Sjchandra	    left_shift64(cipherdst_addr, 0, 40));
350233541Sjchandra}
351233541Sjchandra
352233541Sjchandra/**
353233541Sjchandra  * @brief Generate crypto packet fmn message entry 0
354233541Sjchandra  * @ingroup crypto
355233541Sjchandra  * freeback_vc: freeback response destination address
356233541Sjchandra  * designer_fblen : Designer freeback length, 1 - 4
357233541Sjchandra  * designerdesc_valid : designer desc valid or not
358233541Sjchandra  * cipher_keylen : cipher key length in bytes
359233541Sjchandra  * ctrldesc_addr : physicall address of the control descriptor
360233541Sjchandra  */
361233541Sjchandrastatic __inline__ uint64_t
362233541Sjchandranlm_crypto_form_pkt_fmn_entry0(unsigned int freeback_vc,
363233541Sjchandra    unsigned int designer_fblen, unsigned int designerdesc_valid,
364233541Sjchandra    unsigned int cipher_keylen, uint64_t cntldesc_addr)
365233541Sjchandra{
366233541Sjchandra	return (left_shift64(freeback_vc, 48, 16) |
367233541Sjchandra	    left_shift64_mask(designer_fblen - 1, 46, 2) |
368233541Sjchandra	    left_shift64(designerdesc_valid, 45, 1) |
369233541Sjchandra	    left_shift64_mask(((cipher_keylen + 7) >> 3), 40, 5) |
370233541Sjchandra	    left_shift64(cntldesc_addr >> 6, 0, 34));
371233541Sjchandra}
372233541Sjchandra
373233541Sjchandra/**
374233541Sjchandra  * @brief Generate crypto packet fmn message entry 1
375233541Sjchandra  * @ingroup crypto
376233541Sjchandra  * arc4load_state : 1 if load state required 0 otherwise
377233541Sjchandra  * hash_keylen : hash key length in bytes
378233541Sjchandra  * pktdesc_size : packet descriptor size in bytes
379233541Sjchandra  * pktdesc_addr : physicall address of the packet descriptor
380233541Sjchandra  */
381233541Sjchandrastatic __inline__ uint64_t
382233541Sjchandranlm_crypto_form_pkt_fmn_entry1(unsigned int arc4load_state,
383233541Sjchandra    unsigned int hash_keylen, unsigned int pktdesc_size,
384233541Sjchandra    uint64_t pktdesc_addr)
385233541Sjchandra{
386233541Sjchandra	return (left_shift64(arc4load_state, 63, 1) |
387233541Sjchandra	    left_shift64_mask(((hash_keylen + 7) >> 3), 56, 5) |
388233541Sjchandra	    left_shift64_mask(((pktdesc_size >> 4) - 1), 43, 12) |
389233541Sjchandra	    left_shift64(pktdesc_addr >> 6, 0, 34));
390233541Sjchandra}
391233541Sjchandra
392233541Sjchandrastatic __inline__ int
393233541Sjchandranlm_crypto_get_hklen_taglen(enum nlm_hash_algo hashalg,
394233541Sjchandra    enum nlm_hash_mode hashmode, unsigned int *taglen, unsigned int *hklen)
395233541Sjchandra{
396233541Sjchandra	if (hashalg == NLM_HASH_MD5) {
397233541Sjchandra		*taglen = 128;
398233541Sjchandra		*hklen  = 64;
399233541Sjchandra	} else if (hashalg == NLM_HASH_SHA) {
400233541Sjchandra		switch (hashmode) {
401279387Sjchandra		case NLM_HASH_MODE_SHA1:
402233541Sjchandra			*taglen = 160;
403233541Sjchandra			*hklen  = 64;
404233541Sjchandra			break;
405279387Sjchandra		case NLM_HASH_MODE_SHA224:
406233541Sjchandra			*taglen = 224;
407233541Sjchandra			*hklen  = 64;
408233541Sjchandra			break;
409279387Sjchandra		case NLM_HASH_MODE_SHA256:
410233541Sjchandra			*taglen = 256;
411233541Sjchandra			*hklen  = 64;
412233541Sjchandra			break;
413279387Sjchandra		case NLM_HASH_MODE_SHA384:
414233541Sjchandra			*taglen = 384;
415233541Sjchandra			*hklen  = 128;
416233541Sjchandra			break;
417279387Sjchandra		case NLM_HASH_MODE_SHA512:
418233541Sjchandra			*taglen = 512;
419233541Sjchandra			*hklen  = 128;
420233541Sjchandra			break;
421233541Sjchandra		default:
422233541Sjchandra			printf("Error : invalid shaid (%s)\n", __func__);
423233541Sjchandra			return (-1);
424233541Sjchandra		}
425233541Sjchandra	} else if (hashalg == NLM_HASH_KASUMI_F9) {
426233541Sjchandra		*taglen = 32;
427233541Sjchandra		*hklen  = 0;
428233541Sjchandra	} else if (hashalg == NLM_HASH_SNOW3G_F9) {
429233541Sjchandra		*taglen = 32;
430233541Sjchandra		*hklen  = 0;
431233541Sjchandra	} else if (hashmode == NLM_HASH_MODE_XCBC) {
432233541Sjchandra		*taglen = 128;
433233541Sjchandra		*hklen  = 0;
434233541Sjchandra	} else if (hashmode == NLM_HASH_MODE_GCM) {
435233541Sjchandra		*taglen = 128;
436233541Sjchandra		*hklen  = 0;
437233541Sjchandra	} else if (hashalg == NLM_HASH_BYPASS) {
438233541Sjchandra		*taglen = 0;
439233541Sjchandra		*hklen  = 0;
440233541Sjchandra	} else {
441233541Sjchandra		printf("Error:Hash alg/mode not found\n");
442233541Sjchandra		return (-1);
443233541Sjchandra	}
444233541Sjchandra
445233541Sjchandra	/* TODO : Add remaining cases */
446233541Sjchandra	return (0);
447233541Sjchandra}
448233541Sjchandra
449233541Sjchandra/**
450233541Sjchandra* @brief Generate fill cryto control info structure
451233541Sjchandra* @ingroup crypto
452279387Sjchandra* hmac : 1 for hash with hmac
453233541Sjchandra* hashalg: see above,  hash_alg enums
454233541Sjchandra* hashmode: see above, hash_mode enums
455233541Sjchandra* cipherhalg: see above,  cipher_alg enums
456233541Sjchandra* ciphermode: see above, cipher_mode enums
457233541Sjchandra*
458233541Sjchandra*/
459233541Sjchandrastatic __inline__ int
460233541Sjchandranlm_crypto_fill_pkt_ctrl(struct nlm_crypto_pkt_ctrl *ctrl, unsigned int hmac,
461233541Sjchandra    enum nlm_hash_algo hashalg, enum nlm_hash_mode hashmode,
462233541Sjchandra    enum nlm_cipher_algo cipheralg, enum nlm_cipher_mode ciphermode,
463233541Sjchandra    unsigned char *cipherkey, unsigned int cipherkeylen,
464233541Sjchandra    unsigned char *hashkey, unsigned int hashkeylen)
465233541Sjchandra{
466233541Sjchandra	unsigned int taglen = 0, hklen = 0;
467233541Sjchandra
468279387Sjchandra	ctrl->desc0 = nlm_crypto_form_pkt_ctrl_desc(hmac, hashalg, hashmode,
469233541Sjchandra	    cipheralg, ciphermode, 0, 0, 0);
470233541Sjchandra	memset(ctrl->key, 0, sizeof(ctrl->key));
471233541Sjchandra	if (cipherkey)
472233541Sjchandra		memcpy(ctrl->key, cipherkey, cipherkeylen);
473233541Sjchandra	if (hashkey)
474233541Sjchandra		memcpy((unsigned char *)&ctrl->key[(cipherkeylen + 7) / 8],
475233541Sjchandra			    hashkey, hashkeylen);
476233541Sjchandra	if (nlm_crypto_get_hklen_taglen(hashalg, hashmode, &taglen, &hklen)
477233541Sjchandra	    < 0)
478233541Sjchandra		return (-1);
479233541Sjchandra
480233541Sjchandra	ctrl->cipherkeylen = cipherkeylen;
481233541Sjchandra	ctrl->hashkeylen = hklen;
482233541Sjchandra	ctrl->taglen = taglen;
483279387Sjchandra
484233541Sjchandra	/* TODO : add the invalid checks and return error */
485233541Sjchandra	return (0);
486233541Sjchandra}
487233541Sjchandra
488233541Sjchandra/**
489233541Sjchandra* @brief Top level function for generation pkt desc 0 to 3 for cipher auth
490233541Sjchandra* @ingroup crypto
491233541Sjchandra* ctrl : pointer to control structure
492233541Sjchandra* param : pointer to the param structure
493233541Sjchandra* encrypt : 1(for encrypt) 0(for decrypt)
494233541Sjchandra* hash_source : 1(encrypted data is sent to the auth engine) 0(plain data is
495233541Sjchandra*		sent to the auth engine)
496233541Sjchandra* ivoff : iv offset from start of data
497233541Sjchandra* ivlen : iv length in bytes
498233541Sjchandra* hashoff : hash offset from start of data
499233541Sjchandra* hashlen : hash length in bytes
500233541Sjchandra* hmacpad : hmac padding required or not, 1 if already padded
501233541Sjchandra* cipheroff : cipher offset from start of data
502233541Sjchandra* cipherlen : cipher length in bytes
503233541Sjchandra* hashdst_addr : hash destination physical address
504233541Sjchandra*/
505233541Sjchandrastatic __inline__ void
506233541Sjchandranlm_crypto_fill_cipher_auth_pkt_param(struct nlm_crypto_pkt_ctrl *ctrl,
507233541Sjchandra    struct nlm_crypto_pkt_param *param, unsigned int encrypt,
508233541Sjchandra    unsigned int hash_source, unsigned int ivoff, unsigned int ivlen,
509233541Sjchandra    unsigned int hashoff, unsigned int hashlen, unsigned int hmacpad,
510233541Sjchandra    unsigned int cipheroff, unsigned int cipherlen, unsigned char *hashdst_addr)
511233541Sjchandra{
512233541Sjchandra	param->desc0 = nlm_crypto_form_pkt_desc0(0, hash_source, 1, encrypt,
513233541Sjchandra			   ivlen, vtophys(hashdst_addr));
514233541Sjchandra	param->desc1 = nlm_crypto_form_pkt_desc1(cipherlen, hashlen);
515233541Sjchandra	param->desc2 = nlm_crypto_form_pkt_desc2(ivoff, 0, cipheroff, 0, 0,
516233541Sjchandra			   hashoff);
517233541Sjchandra	param->desc3 = nlm_crypto_form_pkt_desc3(0, ctrl->taglen, 0, 0,
518233541Sjchandra			   hmacpad);
519233541Sjchandra}
520233541Sjchandra
521233541Sjchandra/**
522233541Sjchandra* @brief Top level function for generation pkt desc 0 to 3 for cipher operation
523233541Sjchandra* @ingroup crypto
524233541Sjchandra* ctrl : pointer to control structure
525233541Sjchandra* param : pointer to the param structure
526233541Sjchandra* encrypt : 1(for encrypt) 0(for decrypt)
527233541Sjchandra* ivoff : iv offset from start of data
528233541Sjchandra* ivlen : iv length in bytes
529233541Sjchandra* cipheroff : cipher offset from start of data
530233541Sjchandra* cipherlen : cipher length in bytes
531233541Sjchandra*/
532233541Sjchandrastatic __inline__ void
533233541Sjchandranlm_crypto_fill_cipher_pkt_param(struct nlm_crypto_pkt_ctrl *ctrl,
534233541Sjchandra    struct nlm_crypto_pkt_param *param, unsigned int encrypt,
535233541Sjchandra    unsigned int ivoff, unsigned int ivlen, unsigned int cipheroff,
536233541Sjchandra    unsigned int cipherlen)
537233541Sjchandra{
538233541Sjchandra	param->desc0 = nlm_crypto_form_pkt_desc0(0, 0, 0, encrypt, ivlen, 0ULL);
539233541Sjchandra	param->desc1 = nlm_crypto_form_pkt_desc1(cipherlen, 1);
540233541Sjchandra	param->desc2 = nlm_crypto_form_pkt_desc2(ivoff, 0, cipheroff, 0, 0, 0);
541233541Sjchandra	param->desc3 = nlm_crypto_form_pkt_desc3(0, ctrl->taglen, 0, 0, 0);
542233541Sjchandra}
543233541Sjchandra
544233541Sjchandra/**
545233541Sjchandra* @brief Top level function for generation pkt desc 0 to 3 for auth operation
546233541Sjchandra* @ingroup crypto
547233541Sjchandra* ctrl : pointer to control structure
548233541Sjchandra* param : pointer to the param structure
549233541Sjchandra* hashoff : hash offset from start of data
550233541Sjchandra* hashlen : hash length in bytes
551233541Sjchandra* hmacpad : hmac padding required or not, 1 if already padded
552233541Sjchandra* hashdst_addr : hash destination physical address
553233541Sjchandra*/
554233541Sjchandrastatic __inline__ void
555233541Sjchandranlm_crypto_fill_auth_pkt_param(struct nlm_crypto_pkt_ctrl *ctrl,
556233541Sjchandra    struct nlm_crypto_pkt_param *param, unsigned int hashoff,
557233541Sjchandra    unsigned int hashlen, unsigned int hmacpad, unsigned char *hashdst_addr)
558233541Sjchandra{
559233541Sjchandra	param->desc0 = nlm_crypto_form_pkt_desc0(0, 0, 1, 0, 1,
560233541Sjchandra			   vtophys(hashdst_addr));
561233541Sjchandra	param->desc1 = nlm_crypto_form_pkt_desc1(1, hashlen);
562233541Sjchandra	param->desc2 = nlm_crypto_form_pkt_desc2(0, 0, 0, 0, 0, hashoff);
563233541Sjchandra	param->desc3 = nlm_crypto_form_pkt_desc3(0, ctrl->taglen, 0, 0,
564233541Sjchandra			   hmacpad);
565233541Sjchandra}
566233541Sjchandra
567233541Sjchandrastatic __inline__ unsigned int
568233541Sjchandranlm_crypto_fill_src_seg(struct nlm_crypto_pkt_param *param, int seg,
569233541Sjchandra    unsigned char *input, unsigned int inlen)
570233541Sjchandra{
571233541Sjchandra	unsigned off = 0, len = 0;
572233541Sjchandra	unsigned int remlen = inlen;
573233541Sjchandra
574233541Sjchandra	for (; remlen > 0;) {
575233541Sjchandra		len = remlen > NLM_CRYPTO_MAX_SEG_LEN ?
576233541Sjchandra		    NLM_CRYPTO_MAX_SEG_LEN : remlen;
577233541Sjchandra		param->segment[seg][0] = nlm_crypto_form_pkt_desc4(len,
578233541Sjchandra		    vtophys(input + off));
579233541Sjchandra		remlen -= len;
580233541Sjchandra		off += len;
581233541Sjchandra		seg++;
582233541Sjchandra	}
583233541Sjchandra	return (seg);
584233541Sjchandra}
585233541Sjchandra
586233541Sjchandrastatic __inline__ unsigned int
587279387Sjchandranlm_crypto_fill_dst_seg(struct nlm_crypto_pkt_param *param,
588233541Sjchandra		int seg, unsigned char *output, unsigned int outlen)
589233541Sjchandra{
590233541Sjchandra	unsigned off = 0, len = 0;
591233541Sjchandra	unsigned int remlen = outlen;
592233541Sjchandra
593233541Sjchandra	for (; remlen > 0;) {
594233541Sjchandra		len = remlen > NLM_CRYPTO_MAX_SEG_LEN ?
595233541Sjchandra		    NLM_CRYPTO_MAX_SEG_LEN : remlen;
596233541Sjchandra		param->segment[seg][1] = nlm_crypto_form_pkt_desc5(len, 1, 0,
597233541Sjchandra		    vtophys(output + off));
598233541Sjchandra		remlen -= len;
599233541Sjchandra		off += len;
600233541Sjchandra		seg++;
601233541Sjchandra	}
602233541Sjchandra	return (seg);
603233541Sjchandra}
604233541Sjchandra
605233541Sjchandra#endif
606