1*4332fecaSAllan Jude /*- 2*4332fecaSAllan Jude * Copyright (c) 2005-2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3*4332fecaSAllan Jude * All rights reserved. 4*4332fecaSAllan Jude * 5*4332fecaSAllan Jude * Redistribution and use in source and binary forms, with or without 6*4332fecaSAllan Jude * modification, are permitted provided that the following conditions 7*4332fecaSAllan Jude * are met: 8*4332fecaSAllan Jude * 1. Redistributions of source code must retain the above copyright 9*4332fecaSAllan Jude * notice, this list of conditions and the following disclaimer. 10*4332fecaSAllan Jude * 2. Redistributions in binary form must reproduce the above copyright 11*4332fecaSAllan Jude * notice, this list of conditions and the following disclaimer in the 12*4332fecaSAllan Jude * documentation and/or other materials provided with the distribution. 13*4332fecaSAllan Jude * 14*4332fecaSAllan Jude * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15*4332fecaSAllan Jude * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*4332fecaSAllan Jude * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*4332fecaSAllan Jude * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18*4332fecaSAllan Jude * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*4332fecaSAllan Jude * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*4332fecaSAllan Jude * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*4332fecaSAllan Jude * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*4332fecaSAllan Jude * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*4332fecaSAllan Jude * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*4332fecaSAllan Jude * SUCH DAMAGE. 25*4332fecaSAllan Jude */ 26*4332fecaSAllan Jude 27*4332fecaSAllan Jude #include <sys/cdefs.h> 28*4332fecaSAllan Jude __FBSDID("$FreeBSD$"); 29*4332fecaSAllan Jude 30*4332fecaSAllan Jude #include <sys/param.h> 31*4332fecaSAllan Jude #ifdef _KERNEL 32*4332fecaSAllan Jude #include <sys/systm.h> 33*4332fecaSAllan Jude #include <sys/kernel.h> 34*4332fecaSAllan Jude #include <sys/malloc.h> 35*4332fecaSAllan Jude #else 36*4332fecaSAllan Jude #include <stdint.h> 37*4332fecaSAllan Jude #include <string.h> 38*4332fecaSAllan Jude #include <strings.h> 39*4332fecaSAllan Jude #include <errno.h> 40*4332fecaSAllan Jude #include <assert.h> 41*4332fecaSAllan Jude #include <openssl/evp.h> 42*4332fecaSAllan Jude #define _OpenSSL_ 43*4332fecaSAllan Jude #endif 44*4332fecaSAllan Jude #include <geom/eli/g_eli.h> 45*4332fecaSAllan Jude 46*4332fecaSAllan Jude void 47*4332fecaSAllan Jude g_eli_crypto_hmac_init(struct hmac_ctx *ctx, const uint8_t *hkey, 48*4332fecaSAllan Jude size_t hkeylen) 49*4332fecaSAllan Jude { 50*4332fecaSAllan Jude u_char k_ipad[128], key[128]; 51*4332fecaSAllan Jude SHA512_CTX lctx; 52*4332fecaSAllan Jude u_int i; 53*4332fecaSAllan Jude 54*4332fecaSAllan Jude bzero(key, sizeof(key)); 55*4332fecaSAllan Jude if (hkeylen == 0) 56*4332fecaSAllan Jude ; /* do nothing */ 57*4332fecaSAllan Jude else if (hkeylen <= 128) 58*4332fecaSAllan Jude bcopy(hkey, key, hkeylen); 59*4332fecaSAllan Jude else { 60*4332fecaSAllan Jude /* If key is longer than 128 bytes reset it to key = SHA512(key). */ 61*4332fecaSAllan Jude SHA512_Init(&lctx); 62*4332fecaSAllan Jude SHA512_Update(&lctx, hkey, hkeylen); 63*4332fecaSAllan Jude SHA512_Final(key, &lctx); 64*4332fecaSAllan Jude } 65*4332fecaSAllan Jude 66*4332fecaSAllan Jude /* XOR key with ipad and opad values. */ 67*4332fecaSAllan Jude for (i = 0; i < sizeof(key); i++) { 68*4332fecaSAllan Jude k_ipad[i] = key[i] ^ 0x36; 69*4332fecaSAllan Jude ctx->k_opad[i] = key[i] ^ 0x5c; 70*4332fecaSAllan Jude } 71*4332fecaSAllan Jude bzero(key, sizeof(key)); 72*4332fecaSAllan Jude /* Perform inner SHA512. */ 73*4332fecaSAllan Jude SHA512_Init(&ctx->shactx); 74*4332fecaSAllan Jude SHA512_Update(&ctx->shactx, k_ipad, sizeof(k_ipad)); 75*4332fecaSAllan Jude bzero(k_ipad, sizeof(k_ipad)); 76*4332fecaSAllan Jude } 77*4332fecaSAllan Jude 78*4332fecaSAllan Jude void 79*4332fecaSAllan Jude g_eli_crypto_hmac_update(struct hmac_ctx *ctx, const uint8_t *data, 80*4332fecaSAllan Jude size_t datasize) 81*4332fecaSAllan Jude { 82*4332fecaSAllan Jude 83*4332fecaSAllan Jude SHA512_Update(&ctx->shactx, data, datasize); 84*4332fecaSAllan Jude } 85*4332fecaSAllan Jude 86*4332fecaSAllan Jude void 87*4332fecaSAllan Jude g_eli_crypto_hmac_final(struct hmac_ctx *ctx, uint8_t *md, size_t mdsize) 88*4332fecaSAllan Jude { 89*4332fecaSAllan Jude u_char digest[SHA512_MDLEN]; 90*4332fecaSAllan Jude SHA512_CTX lctx; 91*4332fecaSAllan Jude 92*4332fecaSAllan Jude SHA512_Final(digest, &ctx->shactx); 93*4332fecaSAllan Jude /* Perform outer SHA512. */ 94*4332fecaSAllan Jude SHA512_Init(&lctx); 95*4332fecaSAllan Jude SHA512_Update(&lctx, ctx->k_opad, sizeof(ctx->k_opad)); 96*4332fecaSAllan Jude bzero(ctx, sizeof(*ctx)); 97*4332fecaSAllan Jude SHA512_Update(&lctx, digest, sizeof(digest)); 98*4332fecaSAllan Jude SHA512_Final(digest, &lctx); 99*4332fecaSAllan Jude bzero(&lctx, sizeof(lctx)); 100*4332fecaSAllan Jude /* mdsize == 0 means "Give me the whole hash!" */ 101*4332fecaSAllan Jude if (mdsize == 0) 102*4332fecaSAllan Jude mdsize = SHA512_MDLEN; 103*4332fecaSAllan Jude bcopy(digest, md, mdsize); 104*4332fecaSAllan Jude bzero(digest, sizeof(digest)); 105*4332fecaSAllan Jude } 106*4332fecaSAllan Jude 107*4332fecaSAllan Jude void 108*4332fecaSAllan Jude g_eli_crypto_hmac(const uint8_t *hkey, size_t hkeysize, const uint8_t *data, 109*4332fecaSAllan Jude size_t datasize, uint8_t *md, size_t mdsize) 110*4332fecaSAllan Jude { 111*4332fecaSAllan Jude struct hmac_ctx ctx; 112*4332fecaSAllan Jude 113*4332fecaSAllan Jude g_eli_crypto_hmac_init(&ctx, hkey, hkeysize); 114*4332fecaSAllan Jude g_eli_crypto_hmac_update(&ctx, data, datasize); 115*4332fecaSAllan Jude g_eli_crypto_hmac_final(&ctx, md, mdsize); 116*4332fecaSAllan Jude } 117*4332fecaSAllan Jude 118*4332fecaSAllan Jude /* 119*4332fecaSAllan Jude * Here we generate IV. It is unique for every sector. 120*4332fecaSAllan Jude */ 121*4332fecaSAllan Jude void 122*4332fecaSAllan Jude g_eli_crypto_ivgen(struct g_eli_softc *sc, off_t offset, u_char *iv, 123*4332fecaSAllan Jude size_t size) 124*4332fecaSAllan Jude { 125*4332fecaSAllan Jude uint8_t off[8]; 126*4332fecaSAllan Jude 127*4332fecaSAllan Jude if ((sc->sc_flags & G_ELI_FLAG_NATIVE_BYTE_ORDER) != 0) 128*4332fecaSAllan Jude bcopy(&offset, off, sizeof(off)); 129*4332fecaSAllan Jude else 130*4332fecaSAllan Jude le64enc(off, (uint64_t)offset); 131*4332fecaSAllan Jude 132*4332fecaSAllan Jude switch (sc->sc_ealgo) { 133*4332fecaSAllan Jude case CRYPTO_AES_XTS: 134*4332fecaSAllan Jude bcopy(off, iv, sizeof(off)); 135*4332fecaSAllan Jude bzero(iv + sizeof(off), size - sizeof(off)); 136*4332fecaSAllan Jude break; 137*4332fecaSAllan Jude default: 138*4332fecaSAllan Jude { 139*4332fecaSAllan Jude u_char hash[SHA256_DIGEST_LENGTH]; 140*4332fecaSAllan Jude SHA256_CTX ctx; 141*4332fecaSAllan Jude 142*4332fecaSAllan Jude /* Copy precalculated SHA256 context for IV-Key. */ 143*4332fecaSAllan Jude bcopy(&sc->sc_ivctx, &ctx, sizeof(ctx)); 144*4332fecaSAllan Jude SHA256_Update(&ctx, off, sizeof(off)); 145*4332fecaSAllan Jude SHA256_Final(hash, &ctx); 146*4332fecaSAllan Jude bcopy(hash, iv, MIN(sizeof(hash), size)); 147*4332fecaSAllan Jude break; 148*4332fecaSAllan Jude } 149*4332fecaSAllan Jude } 150*4332fecaSAllan Jude } 151