]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/glxsb/glxsb_hash.c
Merge ACPICA 20200326.
[FreeBSD/FreeBSD.git] / sys / dev / glxsb / glxsb_hash.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/malloc.h>
35
36 #include <opencrypto/cryptosoft.h> /* for hmac_ipad_buffer and hmac_opad_buffer */
37 #include <opencrypto/xform.h>
38
39 #include "glxsb.h"
40
41 /*
42  * Implementation notes.
43  *
44  * The Geode LX Security Block provides AES-128-CBC acceleration.
45  * We implement all HMAC algorithms provided by crypto(9) framework so glxsb can work
46  * with ipsec(4)
47  *
48  * This code was stolen from crypto/via/padlock_hash.c
49  */
50
51 MALLOC_DECLARE(M_GLXSB);
52
53 static void
54 glxsb_hash_key_setup(struct glxsb_session *ses, caddr_t key, int klen)
55 {
56         struct auth_hash *axf;
57         int i;
58
59         klen /= 8;
60         axf = ses->ses_axf;
61
62         for (i = 0; i < klen; i++)
63                 key[i] ^= HMAC_IPAD_VAL;
64
65         axf->Init(ses->ses_ictx);
66         axf->Update(ses->ses_ictx, key, klen);
67         axf->Update(ses->ses_ictx, hmac_ipad_buffer, axf->blocksize - klen);
68
69         for (i = 0; i < klen; i++)
70                 key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
71
72         axf->Init(ses->ses_octx);
73         axf->Update(ses->ses_octx, key, klen);
74         axf->Update(ses->ses_octx, hmac_opad_buffer, axf->blocksize - klen);
75
76         for (i = 0; i < klen; i++)
77                 key[i] ^= HMAC_OPAD_VAL;
78 }
79
80 /*
81  * Compute keyed-hash authenticator.
82  */
83 static int
84 glxsb_authcompute(struct glxsb_session *ses, struct cryptodesc *crd,
85     caddr_t buf, int flags)
86 {
87         u_char hash[HASH_MAX_LEN];
88         struct auth_hash *axf;
89         union authctx ctx;
90         int error;
91
92         axf = ses->ses_axf;
93         bcopy(ses->ses_ictx, &ctx, axf->ctxsize);
94         error = crypto_apply(flags, buf, crd->crd_skip, crd->crd_len,
95             (int (*)(void *, void *, unsigned int))axf->Update, (caddr_t)&ctx);
96         if (error != 0)
97                 return (error);
98         axf->Final(hash, &ctx);
99
100         bcopy(ses->ses_octx, &ctx, axf->ctxsize);
101         axf->Update(&ctx, hash, axf->hashsize);
102         axf->Final(hash, &ctx);
103
104         /* Inject the authentication data */
105         crypto_copyback(flags, buf, crd->crd_inject,
106         ses->ses_mlen == 0 ? axf->hashsize : ses->ses_mlen, hash);
107         return (0);
108 }
109
110 int
111 glxsb_hash_setup(struct glxsb_session *ses, struct cryptoini *macini)
112 {
113
114         ses->ses_mlen = macini->cri_mlen;
115
116         /* Find software structure which describes HMAC algorithm. */
117         switch (macini->cri_alg) {
118         case CRYPTO_NULL_HMAC:
119                 ses->ses_axf = &auth_hash_null;
120                 break;
121         case CRYPTO_MD5_HMAC:
122                 ses->ses_axf = &auth_hash_hmac_md5;
123                 break;
124         case CRYPTO_SHA1_HMAC:
125                 ses->ses_axf = &auth_hash_hmac_sha1;
126                 break;
127         case CRYPTO_RIPEMD160_HMAC:
128                 ses->ses_axf = &auth_hash_hmac_ripemd_160;
129                 break;
130         case CRYPTO_SHA2_256_HMAC:
131                 ses->ses_axf = &auth_hash_hmac_sha2_256;
132                 break;
133         case CRYPTO_SHA2_384_HMAC:
134                 ses->ses_axf = &auth_hash_hmac_sha2_384;
135                 break;
136         case CRYPTO_SHA2_512_HMAC:
137                 ses->ses_axf = &auth_hash_hmac_sha2_512;
138                 break;
139         }
140
141         /* Allocate memory for HMAC inner and outer contexts. */
142         ses->ses_ictx = malloc(ses->ses_axf->ctxsize, M_GLXSB,
143             M_ZERO | M_NOWAIT);
144         ses->ses_octx = malloc(ses->ses_axf->ctxsize, M_GLXSB,
145             M_ZERO | M_NOWAIT);
146         if (ses->ses_ictx == NULL || ses->ses_octx == NULL)
147                 return (ENOMEM);
148
149         /* Setup key if given. */
150         if (macini->cri_key != NULL) {
151                 glxsb_hash_key_setup(ses, macini->cri_key,
152                     macini->cri_klen);
153         }
154         return (0);
155 }
156
157 int
158 glxsb_hash_process(struct glxsb_session *ses, struct cryptodesc *maccrd,
159     struct cryptop *crp)
160 {
161         int error;
162
163         if ((maccrd->crd_flags & CRD_F_KEY_EXPLICIT) != 0)
164                 glxsb_hash_key_setup(ses, maccrd->crd_key, maccrd->crd_klen);
165
166         error = glxsb_authcompute(ses, maccrd, crp->crp_buf, crp->crp_flags);
167         return (error);
168 }
169
170 void
171 glxsb_hash_free(struct glxsb_session *ses)
172 {
173
174         if (ses->ses_ictx != NULL) {
175                 bzero(ses->ses_ictx, ses->ses_axf->ctxsize);
176                 free(ses->ses_ictx, M_GLXSB);
177                 ses->ses_ictx = NULL;
178         }
179         if (ses->ses_octx != NULL) {
180                 bzero(ses->ses_octx, ses->ses_axf->ctxsize);
181                 free(ses->ses_octx, M_GLXSB);
182                 ses->ses_octx = NULL;
183         }
184 }