2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2003-2012 Broadcom Corporation
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/malloc.h>
42 #include <sys/mutex.h>
45 #include <machine/bus.h>
46 #include <machine/md_var.h>
47 #include <machine/cpuregs.h>
52 #include <opencrypto/cryptodev.h>
54 #include <mips/nlm/hal/haldefs.h>
55 #include <mips/nlm/hal/cop2.h>
56 #include <mips/nlm/hal/fmn.h>
57 #include <mips/nlm/hal/mips-extns.h>
58 #include <mips/nlm/hal/nlmsaelib.h>
59 #include <mips/nlm/dev/sec/nlmseclib.h>
62 nlm_crypto_complete_sec_request(struct xlp_sec_softc *sc,
63 struct xlp_sec_command *cmd)
69 fbvc = nlm_cpuid() / CMS_MAX_VCPU_VC;
70 m.msg[0] = m.msg[1] = m.msg[2] = m.msg[3] = 0;
72 m.msg[0] = nlm_crypto_form_pkt_fmn_entry0(fbvc, 0, 0,
73 cmd->ctrlp->cipherkeylen, vtophys(cmd->ctrlp));
75 m.msg[1] = nlm_crypto_form_pkt_fmn_entry1(0, cmd->ctrlp->hashkeylen,
76 NLM_CRYPTO_PKT_DESC_SIZE(cmd->nsegs), vtophys(cmd->paramp));
78 /* Software scratch pad */
79 m.msg[2] = (uintptr_t)cmd;
82 /* Send the message to sec/rsa engine vc */
83 ret = nlm_fmn_msgsend(sc->sec_vc_start, sc->sec_msgsz,
84 FMN_SWCODE_CRYPTO, &m);
87 printf("%s: msgsnd failed (%x)\n", __func__, ret);
95 nlm_crypto_form_srcdst_segs(struct xlp_sec_command *cmd)
97 unsigned int srcseg = 0, dstseg = 0;
98 struct cryptodesc *cipdesc = NULL;
99 struct cryptop *crp = NULL;
102 cipdesc = cmd->enccrd;
104 if (cipdesc != NULL) {
105 /* IV is given as ONE segment to avoid copy */
106 if (cipdesc->crd_flags & CRD_F_IV_EXPLICIT) {
107 srcseg = nlm_crypto_fill_src_seg(cmd->paramp, srcseg,
108 cmd->iv, cmd->ivlen);
109 dstseg = nlm_crypto_fill_dst_seg(cmd->paramp, dstseg,
110 cmd->iv, cmd->ivlen);
114 if (crp->crp_flags & CRYPTO_F_IMBUF) {
115 struct mbuf *m = NULL;
117 m = (struct mbuf *)crp->crp_buf;
119 srcseg = nlm_crypto_fill_src_seg(cmd->paramp, srcseg,
120 mtod(m,caddr_t), m->m_len);
121 if (cipdesc != NULL) {
122 dstseg = nlm_crypto_fill_dst_seg(cmd->paramp,
123 dstseg, mtod(m,caddr_t), m->m_len);
127 } else if (crp->crp_flags & CRYPTO_F_IOV) {
128 struct uio *uio = NULL;
129 struct iovec *iov = NULL;
132 uio = (struct uio *)crp->crp_buf;
133 iov = (struct iovec *)uio->uio_iov;
134 iol = uio->uio_iovcnt;
137 srcseg = nlm_crypto_fill_src_seg(cmd->paramp, srcseg,
138 (caddr_t)iov->iov_base, iov->iov_len);
139 if (cipdesc != NULL) {
140 dstseg = nlm_crypto_fill_dst_seg(cmd->paramp,
141 dstseg, (caddr_t)iov->iov_base,
148 srcseg = nlm_crypto_fill_src_seg(cmd->paramp, srcseg,
149 ((caddr_t)crp->crp_buf), crp->crp_ilen);
150 if (cipdesc != NULL) {
151 dstseg = nlm_crypto_fill_dst_seg(cmd->paramp, dstseg,
152 ((caddr_t)crp->crp_buf), crp->crp_ilen);
159 nlm_crypto_do_cipher(struct xlp_sec_softc *sc, struct xlp_sec_command *cmd)
161 struct cryptodesc *cipdesc = NULL;
162 unsigned char *cipkey = NULL;
165 cipdesc = cmd->enccrd;
166 cipkey = (unsigned char *)cipdesc->crd_key;
167 if (cmd->cipheralg == NLM_CIPHER_3DES) {
168 if (!(cipdesc->crd_flags & CRD_F_ENCRYPT)) {
170 k = (uint64_t *)cipdesc->crd_key;
171 tkey = (uint64_t *)cmd->des3key;
175 cipkey = (unsigned char *)tkey;
178 nlm_crypto_fill_pkt_ctrl(cmd->ctrlp, 0, NLM_HASH_BYPASS, 0,
179 cmd->cipheralg, cmd->ciphermode, cipkey,
180 (cipdesc->crd_klen >> 3), NULL, 0);
182 nlm_crypto_fill_cipher_pkt_param(cmd->ctrlp, cmd->paramp,
183 (cipdesc->crd_flags & CRD_F_ENCRYPT) ? 1 : 0, cmd->ivoff,
184 cmd->ivlen, cmd->cipheroff, cmd->cipherlen);
185 nlm_crypto_form_srcdst_segs(cmd);
187 ret = nlm_crypto_complete_sec_request(sc, cmd);
192 nlm_crypto_do_digest(struct xlp_sec_softc *sc, struct xlp_sec_command *cmd)
194 struct cryptodesc *digdesc = NULL;
197 digdesc = cmd->maccrd;
199 nlm_crypto_fill_pkt_ctrl(cmd->ctrlp, (digdesc->crd_klen) ? 1 : 0,
200 cmd->hashalg, cmd->hashmode, NLM_CIPHER_BYPASS, 0,
201 NULL, 0, digdesc->crd_key, digdesc->crd_klen >> 3);
203 nlm_crypto_fill_auth_pkt_param(cmd->ctrlp, cmd->paramp,
204 cmd->hashoff, cmd->hashlen, cmd->hmacpad,
205 (unsigned char *)cmd->hashdest);
207 nlm_crypto_form_srcdst_segs(cmd);
209 ret = nlm_crypto_complete_sec_request(sc, cmd);
215 nlm_crypto_do_cipher_digest(struct xlp_sec_softc *sc,
216 struct xlp_sec_command *cmd)
218 struct cryptodesc *cipdesc=NULL, *digdesc=NULL;
219 unsigned char *cipkey = NULL;
222 cipdesc = cmd->enccrd;
223 digdesc = cmd->maccrd;
225 cipkey = (unsigned char *)cipdesc->crd_key;
226 if (cmd->cipheralg == NLM_CIPHER_3DES) {
227 if (!(cipdesc->crd_flags & CRD_F_ENCRYPT)) {
229 k = (uint64_t *)cipdesc->crd_key;
230 tkey = (uint64_t *)cmd->des3key;
234 cipkey = (unsigned char *)tkey;
237 nlm_crypto_fill_pkt_ctrl(cmd->ctrlp, (digdesc->crd_klen) ? 1 : 0,
238 cmd->hashalg, cmd->hashmode, cmd->cipheralg, cmd->ciphermode,
239 cipkey, (cipdesc->crd_klen >> 3),
240 digdesc->crd_key, (digdesc->crd_klen >> 3));
242 nlm_crypto_fill_cipher_auth_pkt_param(cmd->ctrlp, cmd->paramp,
243 (cipdesc->crd_flags & CRD_F_ENCRYPT) ? 1 : 0, cmd->hashsrc,
244 cmd->ivoff, cmd->ivlen, cmd->hashoff, cmd->hashlen,
245 cmd->hmacpad, cmd->cipheroff, cmd->cipherlen,
246 (unsigned char *)cmd->hashdest);
248 nlm_crypto_form_srcdst_segs(cmd);
250 ret = nlm_crypto_complete_sec_request(sc, cmd);
255 nlm_get_digest_param(struct xlp_sec_command *cmd)
257 switch(cmd->maccrd->crd_alg) {
259 cmd->hashalg = NLM_HASH_MD5;
260 cmd->hashmode = NLM_HASH_MODE_SHA1;
263 cmd->hashalg = NLM_HASH_SHA;
264 cmd->hashmode = NLM_HASH_MODE_SHA1;
266 case CRYPTO_MD5_HMAC:
267 cmd->hashalg = NLM_HASH_MD5;
268 cmd->hashmode = NLM_HASH_MODE_SHA1;
270 case CRYPTO_SHA1_HMAC:
271 cmd->hashalg = NLM_HASH_SHA;
272 cmd->hashmode = NLM_HASH_MODE_SHA1;
281 nlm_get_cipher_param(struct xlp_sec_command *cmd)
283 switch(cmd->enccrd->crd_alg) {
285 cmd->cipheralg = NLM_CIPHER_DES;
286 cmd->ciphermode = NLM_CIPHER_MODE_CBC;
287 cmd->ivlen = XLP_SEC_DES_IV_LENGTH;
289 case CRYPTO_3DES_CBC:
290 cmd->cipheralg = NLM_CIPHER_3DES;
291 cmd->ciphermode = NLM_CIPHER_MODE_CBC;
292 cmd->ivlen = XLP_SEC_DES_IV_LENGTH;
295 cmd->cipheralg = NLM_CIPHER_AES128;
296 cmd->ciphermode = NLM_CIPHER_MODE_CBC;
297 cmd->ivlen = XLP_SEC_AES_IV_LENGTH;
300 cmd->cipheralg = NLM_CIPHER_ARC4;
301 cmd->ciphermode = NLM_CIPHER_MODE_ECB;
302 cmd->ivlen = XLP_SEC_ARC4_IV_LENGTH;