glxsb_hash.c revision 331722
1260684Skaiw/*- 2276398Semaste * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3260684Skaiw * All rights reserved. 4260684Skaiw * 5260684Skaiw * Redistribution and use in source and binary forms, with or without 6260684Skaiw * modification, are permitted provided that the following conditions 7260684Skaiw * are met: 8260684Skaiw * 1. Redistributions of source code must retain the above copyright 9260684Skaiw * notice, this list of conditions and the following disclaimer. 10260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 11260684Skaiw * notice, this list of conditions and the following disclaimer in the 12260684Skaiw * documentation and/or other materials provided with the distribution. 13260684Skaiw * 14260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17260684Skaiw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24260684Skaiw * SUCH DAMAGE. 25260684Skaiw */ 26260684Skaiw 27260684Skaiw#include <sys/cdefs.h> 28260684Skaiw__FBSDID("$FreeBSD: stable/11/sys/dev/glxsb/glxsb_hash.c 331722 2018-03-29 02:50:57Z eadler $"); 29260684Skaiw 30260684Skaiw#include <sys/param.h> 31260684Skaiw#include <sys/systm.h> 32260684Skaiw#include <sys/malloc.h> 33260684Skaiw 34260684Skaiw#include <opencrypto/cryptosoft.h> /* for hmac_ipad_buffer and hmac_opad_buffer */ 35260684Skaiw#include <opencrypto/xform.h> 36260684Skaiw 37280932Semaste#include "glxsb.h" 38260684Skaiw 39260684Skaiw/* 40260684Skaiw * Implementation notes. 41260684Skaiw * 42260684Skaiw * The Geode LX Security Block provides AES-128-CBC acceleration. 43260684Skaiw * We implement all HMAC algorithms provided by crypto(9) framework so glxsb can work 44260684Skaiw * with ipsec(4) 45260684Skaiw * 46260684Skaiw * This code was stolen from crypto/via/padlock_hash.c 47260684Skaiw */ 48260684Skaiw 49280932SemasteMALLOC_DECLARE(M_GLXSB); 50260684Skaiw 51260684Skaiwstatic void 52260684Skaiwglxsb_hash_key_setup(struct glxsb_session *ses, caddr_t key, int klen) 53260684Skaiw{ 54260684Skaiw struct auth_hash *axf; 55260684Skaiw int i; 56260684Skaiw 57260684Skaiw klen /= 8; 58260684Skaiw axf = ses->ses_axf; 59260684Skaiw 60260684Skaiw for (i = 0; i < klen; i++) 61260684Skaiw key[i] ^= HMAC_IPAD_VAL; 62260684Skaiw 63260684Skaiw axf->Init(ses->ses_ictx); 64260684Skaiw axf->Update(ses->ses_ictx, key, klen); 65260684Skaiw axf->Update(ses->ses_ictx, hmac_ipad_buffer, axf->blocksize - klen); 66260684Skaiw 67260684Skaiw for (i = 0; i < klen; i++) 68260684Skaiw key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL); 69260684Skaiw 70260684Skaiw axf->Init(ses->ses_octx); 71260684Skaiw axf->Update(ses->ses_octx, key, klen); 72260684Skaiw axf->Update(ses->ses_octx, hmac_opad_buffer, axf->blocksize - klen); 73260684Skaiw 74260684Skaiw for (i = 0; i < klen; i++) 75260684Skaiw key[i] ^= HMAC_OPAD_VAL; 76280932Semaste} 77280932Semaste 78280932Semaste/* 79280932Semaste * Compute keyed-hash authenticator. 80280932Semaste */ 81260684Skaiwstatic int 82260684Skaiwglxsb_authcompute(struct glxsb_session *ses, struct cryptodesc *crd, 83260684Skaiw caddr_t buf, int flags) 84260684Skaiw{ 85260684Skaiw u_char hash[HASH_MAX_LEN]; 86260684Skaiw struct auth_hash *axf; 87260684Skaiw union authctx ctx; 88260684Skaiw int error; 89260684Skaiw 90260684Skaiw axf = ses->ses_axf; 91260684Skaiw bcopy(ses->ses_ictx, &ctx, axf->ctxsize); 92260684Skaiw error = crypto_apply(flags, buf, crd->crd_skip, crd->crd_len, 93260684Skaiw (int (*)(void *, void *, unsigned int))axf->Update, (caddr_t)&ctx); 94260684Skaiw if (error != 0) 95260684Skaiw return (error); 96260684Skaiw axf->Final(hash, &ctx); 97260684Skaiw 98260684Skaiw bcopy(ses->ses_octx, &ctx, axf->ctxsize); 99260684Skaiw axf->Update(&ctx, hash, axf->hashsize); 100260684Skaiw axf->Final(hash, &ctx); 101260684Skaiw 102260684Skaiw /* Inject the authentication data */ 103260684Skaiw crypto_copyback(flags, buf, crd->crd_inject, 104260684Skaiw ses->ses_mlen == 0 ? axf->hashsize : ses->ses_mlen, hash); 105260684Skaiw return (0); 106260684Skaiw} 107260684Skaiw 108260684Skaiwint 109260684Skaiwglxsb_hash_setup(struct glxsb_session *ses, struct cryptoini *macini) 110260684Skaiw{ 111260684Skaiw 112260684Skaiw ses->ses_mlen = macini->cri_mlen; 113260684Skaiw 114260684Skaiw /* Find software structure which describes HMAC algorithm. */ 115260684Skaiw switch (macini->cri_alg) { 116260684Skaiw case CRYPTO_NULL_HMAC: 117260684Skaiw ses->ses_axf = &auth_hash_null; 118260684Skaiw break; 119260684Skaiw case CRYPTO_MD5_HMAC: 120260684Skaiw ses->ses_axf = &auth_hash_hmac_md5; 121260684Skaiw break; 122260684Skaiw case CRYPTO_SHA1_HMAC: 123260684Skaiw ses->ses_axf = &auth_hash_hmac_sha1; 124260684Skaiw break; 125260684Skaiw case CRYPTO_RIPEMD160_HMAC: 126260684Skaiw ses->ses_axf = &auth_hash_hmac_ripemd_160; 127260684Skaiw break; 128260684Skaiw case CRYPTO_SHA2_256_HMAC: 129260684Skaiw ses->ses_axf = &auth_hash_hmac_sha2_256; 130260684Skaiw break; 131260684Skaiw case CRYPTO_SHA2_384_HMAC: 132260684Skaiw ses->ses_axf = &auth_hash_hmac_sha2_384; 133260684Skaiw break; 134260684Skaiw case CRYPTO_SHA2_512_HMAC: 135260684Skaiw ses->ses_axf = &auth_hash_hmac_sha2_512; 136260684Skaiw break; 137260684Skaiw } 138260684Skaiw 139260684Skaiw /* Allocate memory for HMAC inner and outer contexts. */ 140260684Skaiw ses->ses_ictx = malloc(ses->ses_axf->ctxsize, M_GLXSB, 141260684Skaiw M_ZERO | M_NOWAIT); 142260684Skaiw ses->ses_octx = malloc(ses->ses_axf->ctxsize, M_GLXSB, 143260684Skaiw M_ZERO | M_NOWAIT); 144260684Skaiw if (ses->ses_ictx == NULL || ses->ses_octx == NULL) 145260684Skaiw return (ENOMEM); 146260684Skaiw 147260684Skaiw /* Setup key if given. */ 148260684Skaiw if (macini->cri_key != NULL) { 149260684Skaiw glxsb_hash_key_setup(ses, macini->cri_key, 150260684Skaiw macini->cri_klen); 151260684Skaiw } 152260684Skaiw return (0); 153260684Skaiw} 154260684Skaiw 155260684Skaiwint 156260684Skaiwglxsb_hash_process(struct glxsb_session *ses, struct cryptodesc *maccrd, 157260684Skaiw struct cryptop *crp) 158260684Skaiw{ 159260684Skaiw int error; 160260684Skaiw 161260684Skaiw if ((maccrd->crd_flags & CRD_F_KEY_EXPLICIT) != 0) 162260684Skaiw glxsb_hash_key_setup(ses, maccrd->crd_key, maccrd->crd_klen); 163260684Skaiw 164260684Skaiw error = glxsb_authcompute(ses, maccrd, crp->crp_buf, crp->crp_flags); 165260684Skaiw return (error); 166260684Skaiw} 167260684Skaiw 168260684Skaiwvoid 169260684Skaiwglxsb_hash_free(struct glxsb_session *ses) 170260684Skaiw{ 171260684Skaiw 172260684Skaiw if (ses->ses_ictx != NULL) { 173260684Skaiw bzero(ses->ses_ictx, ses->ses_axf->ctxsize); 174260684Skaiw free(ses->ses_ictx, M_GLXSB); 175260684Skaiw ses->ses_ictx = NULL; 176260684Skaiw } 177260684Skaiw if (ses->ses_octx != NULL) { 178260684Skaiw bzero(ses->ses_octx, ses->ses_axf->ctxsize); 179260684Skaiw free(ses->ses_octx, M_GLXSB); 180260684Skaiw ses->ses_octx = NULL; 181260684Skaiw } 182260684Skaiw} 183260684Skaiw