1148456Spjd/*- 2220922Spjd * Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel@dawidek.net> 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$"); 29148456Spjd 30148456Spjd#include <sys/param.h> 31148456Spjd#ifdef _KERNEL 32148456Spjd#include <sys/malloc.h> 33148456Spjd#include <sys/systm.h> 34148456Spjd#include <geom/geom.h> 35148456Spjd#else 36148456Spjd#include <stdio.h> 37148456Spjd#include <stdint.h> 38148456Spjd#include <stdlib.h> 39148456Spjd#include <string.h> 40148456Spjd#include <strings.h> 41148456Spjd#include <errno.h> 42148456Spjd#endif 43148456Spjd 44148456Spjd#include <geom/eli/g_eli.h> 45148456Spjd 46213067Spjd#ifdef _KERNEL 47213067SpjdMALLOC_DECLARE(M_ELI); 48213067Spjd#endif 49148456Spjd 50148456Spjd/* 51148456Spjd * Verify if the given 'key' is correct. 52148456Spjd * Return 1 if it is correct and 0 otherwise. 53148456Spjd */ 54148456Spjdstatic int 55148456Spjdg_eli_mkey_verify(const unsigned char *mkey, const unsigned char *key) 56148456Spjd{ 57148456Spjd const unsigned char *odhmac; /* On-disk HMAC. */ 58148456Spjd unsigned char chmac[SHA512_MDLEN]; /* Calculated HMAC. */ 59148456Spjd unsigned char hmkey[SHA512_MDLEN]; /* Key for HMAC. */ 60148456Spjd 61148456Spjd /* 62148456Spjd * The key for HMAC calculations is: hmkey = HMAC_SHA512(Derived-Key, 0) 63148456Spjd */ 64148456Spjd g_eli_crypto_hmac(key, G_ELI_USERKEYLEN, "\x00", 1, hmkey, 0); 65148456Spjd 66148456Spjd odhmac = mkey + G_ELI_DATAIVKEYLEN; 67148456Spjd 68148456Spjd /* Calculate HMAC from Data-Key and IV-Key. */ 69148456Spjd g_eli_crypto_hmac(hmkey, sizeof(hmkey), mkey, G_ELI_DATAIVKEYLEN, 70148456Spjd chmac, 0); 71148456Spjd 72148456Spjd bzero(hmkey, sizeof(hmkey)); 73148456Spjd 74148456Spjd /* 75148456Spjd * Compare calculated HMAC with HMAC from metadata. 76148456Spjd * If two HMACs are equal, 'key' is correct. 77148456Spjd */ 78148456Spjd return (!bcmp(odhmac, chmac, SHA512_MDLEN)); 79148456Spjd} 80148456Spjd 81148456Spjd/* 82148456Spjd * Calculate HMAC from Data-Key and IV-Key. 83148456Spjd */ 84148456Spjdvoid 85148456Spjdg_eli_mkey_hmac(unsigned char *mkey, const unsigned char *key) 86148456Spjd{ 87148456Spjd unsigned char hmkey[SHA512_MDLEN]; /* Key for HMAC. */ 88148456Spjd unsigned char *odhmac; /* On-disk HMAC. */ 89148456Spjd 90148456Spjd /* 91148456Spjd * The key for HMAC calculations is: hmkey = HMAC_SHA512(Derived-Key, 0) 92148456Spjd */ 93148456Spjd g_eli_crypto_hmac(key, G_ELI_USERKEYLEN, "\x00", 1, hmkey, 0); 94148456Spjd 95148456Spjd odhmac = mkey + G_ELI_DATAIVKEYLEN; 96148456Spjd /* Calculate HMAC from Data-Key and IV-Key. */ 97148456Spjd g_eli_crypto_hmac(hmkey, sizeof(hmkey), mkey, G_ELI_DATAIVKEYLEN, 98148456Spjd odhmac, 0); 99148456Spjd 100148456Spjd bzero(hmkey, sizeof(hmkey)); 101148456Spjd} 102148456Spjd 103148456Spjd/* 104148456Spjd * Find and decrypt Master Key encrypted with 'key'. 105148456Spjd * Return decrypted Master Key number in 'nkeyp' if not NULL. 106148456Spjd * Return 0 on success, > 0 on failure, -1 on bad key. 107148456Spjd */ 108148456Spjdint 109148456Spjdg_eli_mkey_decrypt(const struct g_eli_metadata *md, const unsigned char *key, 110148456Spjd unsigned char *mkey, unsigned *nkeyp) 111148456Spjd{ 112148456Spjd unsigned char tmpmkey[G_ELI_MKEYLEN]; 113148456Spjd unsigned char enckey[SHA512_MDLEN]; /* Key for encryption. */ 114148456Spjd const unsigned char *mmkey; 115148456Spjd int bit, error, nkey; 116148456Spjd 117148456Spjd if (nkeyp != NULL) 118148456Spjd *nkeyp = -1; 119148456Spjd 120148456Spjd /* 121148456Spjd * The key for encryption is: enckey = HMAC_SHA512(Derived-Key, 1) 122148456Spjd */ 123148456Spjd g_eli_crypto_hmac(key, G_ELI_USERKEYLEN, "\x01", 1, enckey, 0); 124148456Spjd 125148456Spjd mmkey = md->md_mkeys; 126148456Spjd for (nkey = 0; nkey < G_ELI_MAXMKEYS; nkey++, mmkey += G_ELI_MKEYLEN) { 127148456Spjd bit = (1 << nkey); 128159307Spjd if (!(md->md_keys & bit)) 129148456Spjd continue; 130148456Spjd bcopy(mmkey, tmpmkey, G_ELI_MKEYLEN); 131159307Spjd error = g_eli_crypto_decrypt(md->md_ealgo, tmpmkey, 132148456Spjd G_ELI_MKEYLEN, enckey, md->md_keylen); 133148456Spjd if (error != 0) { 134148456Spjd bzero(tmpmkey, sizeof(tmpmkey)); 135148456Spjd bzero(enckey, sizeof(enckey)); 136148456Spjd return (error); 137148456Spjd } 138148456Spjd if (g_eli_mkey_verify(tmpmkey, key)) { 139148456Spjd bcopy(tmpmkey, mkey, G_ELI_DATAIVKEYLEN); 140148456Spjd bzero(tmpmkey, sizeof(tmpmkey)); 141148456Spjd bzero(enckey, sizeof(enckey)); 142148456Spjd if (nkeyp != NULL) 143148456Spjd *nkeyp = nkey; 144148456Spjd return (0); 145148456Spjd } 146148456Spjd } 147148456Spjd bzero(enckey, sizeof(enckey)); 148148456Spjd bzero(tmpmkey, sizeof(tmpmkey)); 149148456Spjd return (-1); 150148456Spjd} 151148456Spjd 152148456Spjd/* 153148456Spjd * Encrypt the Master-Key and calculate HMAC to be able to verify it in the 154148456Spjd * future. 155148456Spjd */ 156148456Spjdint 157148456Spjdg_eli_mkey_encrypt(unsigned algo, const unsigned char *key, unsigned keylen, 158148456Spjd unsigned char *mkey) 159148456Spjd{ 160148456Spjd unsigned char enckey[SHA512_MDLEN]; /* Key for encryption. */ 161148456Spjd int error; 162148456Spjd 163148456Spjd /* 164148456Spjd * To calculate HMAC, the whole key (G_ELI_USERKEYLEN bytes long) will 165148456Spjd * be used. 166148456Spjd */ 167148456Spjd g_eli_mkey_hmac(mkey, key); 168148456Spjd /* 169148456Spjd * The key for encryption is: enckey = HMAC_SHA512(Derived-Key, 1) 170148456Spjd */ 171148456Spjd g_eli_crypto_hmac(key, G_ELI_USERKEYLEN, "\x01", 1, enckey, 0); 172148456Spjd /* 173148456Spjd * Encrypt the Master-Key and HMAC() result with the given key (this 174148456Spjd * time only 'keylen' bits from the key are used). 175148456Spjd */ 176148456Spjd error = g_eli_crypto_encrypt(algo, mkey, G_ELI_MKEYLEN, enckey, keylen); 177148456Spjd 178148456Spjd bzero(enckey, sizeof(enckey)); 179148456Spjd 180148456Spjd return (error); 181148456Spjd} 182159307Spjd 183159307Spjd#ifdef _KERNEL 184159307Spjd/* 185159307Spjd * When doing encryption only, copy IV key and encryption key. 186159307Spjd * When doing encryption and authentication, copy IV key, generate encryption 187159307Spjd * key and generate authentication key. 188159307Spjd */ 189159307Spjdvoid 190159307Spjdg_eli_mkey_propagate(struct g_eli_softc *sc, const unsigned char *mkey) 191159307Spjd{ 192159307Spjd 193159307Spjd /* Remember the Master Key. */ 194159307Spjd bcopy(mkey, sc->sc_mkey, sizeof(sc->sc_mkey)); 195159307Spjd 196159307Spjd bcopy(mkey, sc->sc_ivkey, sizeof(sc->sc_ivkey)); 197159307Spjd mkey += sizeof(sc->sc_ivkey); 198159307Spjd 199213067Spjd /* 200213067Spjd * The authentication key is: akey = HMAC_SHA512(Master-Key, 0x11) 201213067Spjd */ 202213067Spjd if ((sc->sc_flags & G_ELI_FLAG_AUTH) != 0) { 203213067Spjd g_eli_crypto_hmac(mkey, G_ELI_MAXKEYLEN, "\x11", 1, 204213067Spjd sc->sc_akey, 0); 205159307Spjd } else { 206213067Spjd arc4rand(sc->sc_akey, sizeof(sc->sc_akey), 0); 207159307Spjd } 208159307Spjd 209220922Spjd /* Initialize encryption keys. */ 210220922Spjd g_eli_key_init(sc); 211214225Spjd 212214225Spjd if (sc->sc_flags & G_ELI_FLAG_AUTH) { 213214225Spjd /* 214214225Spjd * Precalculate SHA256 for HMAC key generation. 215214225Spjd * This is expensive operation and we can do it only once now or 216214225Spjd * for every access to sector, so now will be much better. 217214225Spjd */ 218214225Spjd SHA256_Init(&sc->sc_akeyctx); 219214225Spjd SHA256_Update(&sc->sc_akeyctx, sc->sc_akey, 220214225Spjd sizeof(sc->sc_akey)); 221214225Spjd } 222214225Spjd /* 223214225Spjd * Precalculate SHA256 for IV generation. 224214225Spjd * This is expensive operation and we can do it only once now or for 225214225Spjd * every access to sector, so now will be much better. 226214225Spjd */ 227214225Spjd switch (sc->sc_ealgo) { 228214225Spjd case CRYPTO_AES_XTS: 229214225Spjd break; 230214225Spjd default: 231214225Spjd SHA256_Init(&sc->sc_ivctx); 232214225Spjd SHA256_Update(&sc->sc_ivctx, sc->sc_ivkey, 233214225Spjd sizeof(sc->sc_ivkey)); 234214225Spjd break; 235214225Spjd } 236159307Spjd} 237159307Spjd#endif 238