1148456Spjd/*- 2213072Spjd * Copyright (c) 2005-2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3148456Spjd * All rights reserved. 4148456Spjd * 5148456Spjd * Redistribution and use in source and binary forms, with or without 6148456Spjd * modification, are permitted provided that the following conditions 7148456Spjd * are met: 8148456Spjd * 1. Redistributions of source code must retain the above copyright 9148456Spjd * notice, this list of conditions and the following disclaimer. 10148456Spjd * 2. Redistributions in binary form must reproduce the above copyright 11148456Spjd * notice, this list of conditions and the following disclaimer in the 12148456Spjd * documentation and/or other materials provided with the distribution. 13155174Spjd * 14148456Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15148456Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16148456Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17148456Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18148456Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19148456Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20148456Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21148456Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22148456Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23148456Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24148456Spjd * SUCH DAMAGE. 25148456Spjd */ 26148456Spjd 27148456Spjd#include <sys/cdefs.h> 28148456Spjd__FBSDID("$FreeBSD: releng/11.0/sys/geom/eli/g_eli_hmac.c 293306 2016-01-07 05:47:34Z allanjude $"); 29148456Spjd 30148456Spjd#include <sys/param.h> 31148456Spjd#ifdef _KERNEL 32148456Spjd#include <sys/systm.h> 33148456Spjd#include <sys/kernel.h> 34148456Spjd#include <sys/malloc.h> 35148456Spjd#else 36148456Spjd#include <stdint.h> 37148456Spjd#include <string.h> 38148456Spjd#include <strings.h> 39148456Spjd#include <errno.h> 40148456Spjd#include <assert.h> 41148456Spjd#include <openssl/evp.h> 42148456Spjd#define _OpenSSL_ 43148456Spjd#endif 44148456Spjd#include <geom/eli/g_eli.h> 45148456Spjd 46148456Spjdvoid 47148456Spjdg_eli_crypto_hmac_init(struct hmac_ctx *ctx, const uint8_t *hkey, 48148456Spjd size_t hkeylen) 49148456Spjd{ 50148456Spjd u_char k_ipad[128], key[128]; 51148456Spjd SHA512_CTX lctx; 52148456Spjd u_int i; 53148456Spjd 54148456Spjd bzero(key, sizeof(key)); 55148456Spjd if (hkeylen == 0) 56148456Spjd ; /* do nothing */ 57148456Spjd else if (hkeylen <= 128) 58148456Spjd bcopy(hkey, key, hkeylen); 59148456Spjd else { 60148456Spjd /* If key is longer than 128 bytes reset it to key = SHA512(key). */ 61148456Spjd SHA512_Init(&lctx); 62148456Spjd SHA512_Update(&lctx, hkey, hkeylen); 63148456Spjd SHA512_Final(key, &lctx); 64148456Spjd } 65148456Spjd 66148456Spjd /* XOR key with ipad and opad values. */ 67148456Spjd for (i = 0; i < sizeof(key); i++) { 68148456Spjd k_ipad[i] = key[i] ^ 0x36; 69148456Spjd ctx->k_opad[i] = key[i] ^ 0x5c; 70148456Spjd } 71148456Spjd bzero(key, sizeof(key)); 72148456Spjd /* Perform inner SHA512. */ 73148456Spjd SHA512_Init(&ctx->shactx); 74148456Spjd SHA512_Update(&ctx->shactx, k_ipad, sizeof(k_ipad)); 75261618Sdelphij bzero(k_ipad, sizeof(k_ipad)); 76148456Spjd} 77148456Spjd 78148456Spjdvoid 79148456Spjdg_eli_crypto_hmac_update(struct hmac_ctx *ctx, const uint8_t *data, 80148456Spjd size_t datasize) 81148456Spjd{ 82148456Spjd 83148456Spjd SHA512_Update(&ctx->shactx, data, datasize); 84148456Spjd} 85148456Spjd 86148456Spjdvoid 87148456Spjdg_eli_crypto_hmac_final(struct hmac_ctx *ctx, uint8_t *md, size_t mdsize) 88148456Spjd{ 89148456Spjd u_char digest[SHA512_MDLEN]; 90148456Spjd SHA512_CTX lctx; 91148456Spjd 92148456Spjd SHA512_Final(digest, &ctx->shactx); 93148456Spjd /* Perform outer SHA512. */ 94148456Spjd SHA512_Init(&lctx); 95148456Spjd SHA512_Update(&lctx, ctx->k_opad, sizeof(ctx->k_opad)); 96148456Spjd bzero(ctx, sizeof(*ctx)); 97148456Spjd SHA512_Update(&lctx, digest, sizeof(digest)); 98148456Spjd SHA512_Final(digest, &lctx); 99259429Spjd bzero(&lctx, sizeof(lctx)); 100148456Spjd /* mdsize == 0 means "Give me the whole hash!" */ 101148456Spjd if (mdsize == 0) 102148456Spjd mdsize = SHA512_MDLEN; 103148456Spjd bcopy(digest, md, mdsize); 104259429Spjd bzero(digest, sizeof(digest)); 105148456Spjd} 106148456Spjd 107148456Spjdvoid 108148456Spjdg_eli_crypto_hmac(const uint8_t *hkey, size_t hkeysize, const uint8_t *data, 109148456Spjd size_t datasize, uint8_t *md, size_t mdsize) 110148456Spjd{ 111148456Spjd struct hmac_ctx ctx; 112148456Spjd 113148456Spjd g_eli_crypto_hmac_init(&ctx, hkey, hkeysize); 114148456Spjd g_eli_crypto_hmac_update(&ctx, data, datasize); 115148456Spjd g_eli_crypto_hmac_final(&ctx, md, mdsize); 116148456Spjd} 117293306Sallanjude 118293306Sallanjude/* 119293306Sallanjude * Here we generate IV. It is unique for every sector. 120293306Sallanjude */ 121293306Sallanjudevoid 122293306Sallanjudeg_eli_crypto_ivgen(struct g_eli_softc *sc, off_t offset, u_char *iv, 123293306Sallanjude size_t size) 124293306Sallanjude{ 125293306Sallanjude uint8_t off[8]; 126293306Sallanjude 127293306Sallanjude if ((sc->sc_flags & G_ELI_FLAG_NATIVE_BYTE_ORDER) != 0) 128293306Sallanjude bcopy(&offset, off, sizeof(off)); 129293306Sallanjude else 130293306Sallanjude le64enc(off, (uint64_t)offset); 131293306Sallanjude 132293306Sallanjude switch (sc->sc_ealgo) { 133293306Sallanjude case CRYPTO_AES_XTS: 134293306Sallanjude bcopy(off, iv, sizeof(off)); 135293306Sallanjude bzero(iv + sizeof(off), size - sizeof(off)); 136293306Sallanjude break; 137293306Sallanjude default: 138293306Sallanjude { 139293306Sallanjude u_char hash[SHA256_DIGEST_LENGTH]; 140293306Sallanjude SHA256_CTX ctx; 141293306Sallanjude 142293306Sallanjude /* Copy precalculated SHA256 context for IV-Key. */ 143293306Sallanjude bcopy(&sc->sc_ivctx, &ctx, sizeof(ctx)); 144293306Sallanjude SHA256_Update(&ctx, off, sizeof(off)); 145293306Sallanjude SHA256_Final(hash, &ctx); 146293306Sallanjude bcopy(hash, iv, MIN(sizeof(hash), size)); 147293306Sallanjude break; 148293306Sallanjude } 149293306Sallanjude } 150293306Sallanjude} 151