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