g_bde_crypt.c revision 111964
1105464Sphk/*- 2105464Sphk * Copyright (c) 2002 Poul-Henning Kamp 3105464Sphk * Copyright (c) 2002 Networks Associates Technology, Inc. 4105464Sphk * All rights reserved. 5105464Sphk * 6105464Sphk * This software was developed for the FreeBSD Project by Poul-Henning Kamp 7105464Sphk * and NAI Labs, the Security Research Division of Network Associates, Inc. 8105464Sphk * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 9105464Sphk * DARPA CHATS research program. 10105464Sphk * 11105464Sphk * Redistribution and use in source and binary forms, with or without 12105464Sphk * modification, are permitted provided that the following conditions 13105464Sphk * are met: 14105464Sphk * 1. Redistributions of source code must retain the above copyright 15105464Sphk * notice, this list of conditions and the following disclaimer. 16105464Sphk * 2. Redistributions in binary form must reproduce the above copyright 17105464Sphk * notice, this list of conditions and the following disclaimer in the 18105464Sphk * documentation and/or other materials provided with the distribution. 19105464Sphk * 20105464Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21105464Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22105464Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23105464Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24105464Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25105464Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26105464Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27105464Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28105464Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29105464Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30105464Sphk * SUCH DAMAGE. 31105464Sphk * 32105464Sphk * $FreeBSD: head/sys/geom/bde/g_bde_crypt.c 111964 2003-03-07 19:09:46Z phk $ 33105464Sphk * 34105464Sphk * This source file contains the functions responsible for the crypto, keying 35105464Sphk * and mapping operations on the I/O requests. 36105464Sphk * 37105464Sphk */ 38105464Sphk 39105464Sphk#include <sys/param.h> 40105464Sphk#include <sys/stdint.h> 41105464Sphk#include <sys/bio.h> 42105464Sphk#include <sys/lock.h> 43105464Sphk#include <sys/mutex.h> 44105464Sphk#include <sys/queue.h> 45105464Sphk#include <sys/malloc.h> 46105464Sphk#include <sys/libkern.h> 47105464Sphk#include <sys/md5.h> 48105464Sphk 49106407Sphk#include <crypto/rijndael/rijndael.h> 50106407Sphk#include <crypto/sha2/sha2.h> 51106407Sphk 52105464Sphk#include <geom/geom.h> 53105464Sphk#include <geom/bde/g_bde.h> 54105464Sphk 55105464Sphk 56105464Sphk/* 57105464Sphk * Derive kkey from mkey + sector offset. 58105464Sphk * 59105464Sphk * Security objective: Derive a potentially very large number of distinct skeys 60105464Sphk * from the comparatively small key material in our mkey, in such a way that 61105464Sphk * if one, more or even many of the kkeys are compromised, this does not 62105464Sphk * significantly help an attack on other kkeys and in particular does not 63105464Sphk * weaken or compromised the mkey. 64105464Sphk * 65106226Sphk * First we MD5 hash the sectornumber with the salt from the lock sector. 66106226Sphk * The salt prevents the precalculation and statistical analysis of the MD5 67106226Sphk * output which would be possible if we only gave it the sectornumber. 68105464Sphk * 69106226Sphk * The MD5 hash is used to pick out 16 bytes from the masterkey, which 70106226Sphk * are then hashed with MD5 together with the sector number. 71105464Sphk * 72106226Sphk * The resulting MD5 hash is the kkey. 73105464Sphk */ 74105464Sphk 75105464Sphkstatic void 76105464Sphkg_bde_kkey(struct g_bde_softc *sc, keyInstance *ki, int dir, off_t sector) 77105464Sphk{ 78106226Sphk u_int t; 79105464Sphk MD5_CTX ct; 80106226Sphk u_char buf[16]; 81106407Sphk u_char buf2[8]; 82105464Sphk 83106407Sphk /* We have to be architecture neutral */ 84106407Sphk g_enc_le8(buf2, sector); 85106407Sphk 86105464Sphk MD5Init(&ct); 87106226Sphk MD5Update(&ct, sc->key.salt, 8); 88106407Sphk MD5Update(&ct, buf2, sizeof buf2); 89106226Sphk MD5Update(&ct, sc->key.salt + 8, 8); 90106226Sphk MD5Final(buf, &ct); 91106226Sphk 92106226Sphk MD5Init(&ct); 93106226Sphk for (t = 0; t < 16; t++) { 94106226Sphk MD5Update(&ct, &sc->key.mkey[buf[t]], 1); 95106226Sphk if (t == 8) 96106407Sphk MD5Update(&ct, buf2, sizeof buf2); 97105464Sphk } 98106407Sphk bzero(buf2, sizeof buf2); 99105464Sphk MD5Final(buf, &ct); 100105464Sphk bzero(&ct, sizeof ct); 101105464Sphk AES_makekey(ki, dir, G_BDE_KKEYBITS, buf); 102105464Sphk bzero(buf, sizeof buf); 103105464Sphk} 104105464Sphk 105105464Sphk/* 106105464Sphk * Encryption work for read operation. 107105464Sphk * 108105464Sphk * Security objective: Find the kkey, find the skey, decrypt the sector data. 109105464Sphk */ 110105464Sphk 111105464Sphkvoid 112105464Sphkg_bde_crypt_read(struct g_bde_work *wp) 113105464Sphk{ 114105464Sphk struct g_bde_softc *sc; 115105464Sphk u_char *d; 116105464Sphk u_int n; 117105464Sphk off_t o; 118105464Sphk u_char skey[G_BDE_SKEYLEN]; 119105464Sphk keyInstance ki; 120105464Sphk cipherInstance ci; 121105464Sphk 122105464Sphk 123105464Sphk AES_init(&ci); 124105464Sphk sc = wp->softc; 125105464Sphk o = 0; 126105464Sphk for (n = 0; o < wp->length; n++, o += sc->sectorsize) { 127105464Sphk d = (u_char *)wp->ksp->data + wp->ko + n * G_BDE_SKEYLEN; 128105464Sphk g_bde_kkey(sc, &ki, DIR_DECRYPT, wp->offset + o); 129105464Sphk AES_decrypt(&ci, &ki, d, skey, sizeof skey); 130105464Sphk d = (u_char *)wp->data + o; 131105464Sphk AES_makekey(&ki, DIR_DECRYPT, G_BDE_SKEYBITS, skey); 132105464Sphk AES_decrypt(&ci, &ki, d, d, sc->sectorsize); 133105464Sphk } 134105464Sphk bzero(skey, sizeof skey); 135105464Sphk bzero(&ci, sizeof ci); 136105464Sphk bzero(&ki, sizeof ci); 137105464Sphk} 138105464Sphk 139105464Sphk/* 140105464Sphk * Encryption work for write operation. 141105464Sphk * 142105464Sphk * Security objective: Create random skey, encrypt sector data, 143105464Sphk * encrypt skey with the kkey. 144105464Sphk */ 145105464Sphk 146105464Sphkvoid 147105464Sphkg_bde_crypt_write(struct g_bde_work *wp) 148105464Sphk{ 149105464Sphk u_char *s, *d; 150105464Sphk struct g_bde_softc *sc; 151105464Sphk u_int n; 152105464Sphk off_t o; 153105464Sphk u_char skey[G_BDE_SKEYLEN]; 154105464Sphk keyInstance ki; 155105464Sphk cipherInstance ci; 156105464Sphk 157105464Sphk sc = wp->softc; 158105464Sphk AES_init(&ci); 159105464Sphk o = 0; 160105464Sphk for (n = 0; o < wp->length; n++, o += sc->sectorsize) { 161105464Sphk 162105464Sphk s = (u_char *)wp->data + o; 163105464Sphk d = (u_char *)wp->sp->data + o; 164105464Sphk arc4rand(&skey, sizeof skey, 0); 165105464Sphk AES_makekey(&ki, DIR_ENCRYPT, G_BDE_SKEYBITS, skey); 166105464Sphk AES_encrypt(&ci, &ki, s, d, sc->sectorsize); 167105464Sphk 168105464Sphk d = (u_char *)wp->ksp->data + wp->ko + n * G_BDE_SKEYLEN; 169105464Sphk g_bde_kkey(sc, &ki, DIR_ENCRYPT, wp->offset + o); 170105464Sphk AES_encrypt(&ci, &ki, skey, d, sizeof skey); 171105464Sphk bzero(skey, sizeof skey); 172105464Sphk } 173105464Sphk bzero(skey, sizeof skey); 174105464Sphk bzero(&ci, sizeof ci); 175105464Sphk bzero(&ki, sizeof ci); 176105464Sphk} 177105464Sphk 178105464Sphk/* 179105464Sphk * Encryption work for delete operation. 180105464Sphk * 181105464Sphk * Security objective: Write random data to the sectors. 182105464Sphk * 183105464Sphk * XXX: At a hit in performance we would trash the encrypted skey as well. 184105464Sphk * XXX: This would add frustration to the cleaning lady attack by making 185105464Sphk * XXX: deletes look like writes. 186105464Sphk */ 187105464Sphk 188105464Sphkvoid 189105464Sphkg_bde_crypt_delete(struct g_bde_work *wp) 190105464Sphk{ 191105464Sphk struct g_bde_softc *sc; 192105464Sphk u_char *d; 193105464Sphk off_t o; 194107451Sphk u_char skey[G_BDE_SKEYLEN]; 195107451Sphk keyInstance ki; 196107451Sphk cipherInstance ci; 197105464Sphk 198105464Sphk sc = wp->softc; 199105464Sphk d = wp->sp->data; 200107451Sphk AES_init(&ci); 201105464Sphk /* 202105464Sphk * Do not unroll this loop! 203105464Sphk * Our zone may be significantly wider than the amount of random 204105464Sphk * bytes arc4rand likes to give in one reseeding, whereas our 205105464Sphk * sectorsize is far more likely to be in the same range. 206105464Sphk */ 207105464Sphk for (o = 0; o < wp->length; o += sc->sectorsize) { 208105464Sphk arc4rand(d, sc->sectorsize, 0); 209107451Sphk arc4rand(&skey, sizeof skey, 0); 210107451Sphk AES_makekey(&ki, DIR_ENCRYPT, G_BDE_SKEYBITS, skey); 211107451Sphk AES_encrypt(&ci, &ki, d, d, sc->sectorsize); 212105464Sphk d += sc->sectorsize; 213105464Sphk } 214105464Sphk /* 215105464Sphk * Having written a long random sequence to disk here, we want to 216105464Sphk * force a reseed, to avoid weakening the next time we use random 217105464Sphk * data for something important. 218105464Sphk */ 219105464Sphk arc4rand(&o, sizeof o, 1); 220105464Sphk} 221105464Sphk 222105464Sphk/* 223105464Sphk * Calculate the total payload size of the encrypted device. 224105464Sphk * 225105464Sphk * Security objectives: none. 226105464Sphk * 227105464Sphk * This function needs to agree with g_bde_map_sector() about things. 228105464Sphk */ 229105464Sphk 230105464Sphkuint64_t 231105464Sphkg_bde_max_sector(struct g_bde_key *kp) 232105464Sphk{ 233105464Sphk uint64_t maxsect; 234105464Sphk 235105464Sphk maxsect = kp->media_width; 236105464Sphk maxsect /= kp->zone_width; 237105464Sphk maxsect *= kp->zone_cont; 238105464Sphk return (maxsect); 239105464Sphk} 240105464Sphk 241105464Sphk/* 242105464Sphk * Convert an unencrypted side offset to offsets on the encrypted side. 243105464Sphk * 244105464Sphk * Security objective: Make it harder to identify what sectors contain what 245105464Sphk * on a "cold" disk image. 246105464Sphk * 247105464Sphk * We do this by adding the "keyoffset" from the lock to the physical sector 248108558Sphk * number modulus the available number of sectors. Since all physical sectors 249108558Sphk * presumably look the same cold, this will do. 250105464Sphk * 251108558Sphk * As part of the mapping we have to skip the lock sectors which we know 252108558Sphk * the physical address off. We also truncate the work packet, respecting 253108558Sphk * zone boundaries and lock sectors, so that we end up with a sequence of 254108558Sphk * sectors which are physically contiguous. 255108558Sphk * 256105464Sphk * Shuffling things further is an option, but the incremental frustration is 257105464Sphk * not currently deemed worth the run-time performance hit resulting from the 258105464Sphk * increased number of disk arm movements it would incur. 259105464Sphk * 260105464Sphk * This function offers nothing but a trivial diversion for an attacker able 261105464Sphk * to do "the cleaning lady attack" in its current static mapping form. 262105464Sphk */ 263105464Sphk 264105464Sphkvoid 265108558Sphkg_bde_map_sector(struct g_bde_work *wp) 266105464Sphk{ 267105464Sphk 268108558Sphk u_int zone, zoff, u, len; 269108558Sphk uint64_t ko; 270108558Sphk struct g_bde_softc *sc; 271108558Sphk struct g_bde_key *kp; 272105464Sphk 273108558Sphk sc = wp->softc; 274108558Sphk kp = &sc->key; 275105464Sphk 276108558Sphk /* find which zone and the offset in it */ 277108558Sphk zone = wp->offset / kp->zone_cont; 278108558Sphk zoff = wp->offset % kp->zone_cont; 279105464Sphk 280108558Sphk /* Calculate the offset of the key in the key sector */ 281108558Sphk wp->ko = (zoff / kp->sectorsize) * G_BDE_SKEYLEN; 282105464Sphk 283108558Sphk /* restrict length to that zone */ 284108558Sphk len = kp->zone_cont - zoff; 285111964Sphk 286111964Sphk /* ... and in general */ 287111964Sphk if (len > DFLTPHYS) 288111964Sphk len = DFLTPHYS; 289111964Sphk 290108558Sphk if (len < wp->length) 291108558Sphk wp->length = len; 292105464Sphk 293108558Sphk /* Find physical sector address */ 294108558Sphk wp->so = zone * kp->zone_width + zoff; 295108558Sphk wp->so += kp->keyoffset; 296108558Sphk wp->so %= kp->media_width; 297108558Sphk wp->so += kp->sector0; 298108558Sphk 299105464Sphk /* The key sector is the last in this zone. */ 300108558Sphk wp->kso = zone * kp->zone_width + kp->zone_cont; 301108558Sphk wp->kso += kp->keyoffset; 302108558Sphk wp->kso %= kp->media_width; 303108558Sphk wp->kso += kp->sector0; 304105464Sphk 305108558Sphk /* Compensate for lock sectors */ 306108558Sphk for (u = 0; u < G_BDE_MAXKEYS; u++) { 307108558Sphk /* Find the start of this lock sector */ 308108558Sphk ko = kp->lsector[u] & ~(kp->sectorsize - 1); 309105464Sphk 310108558Sphk if (wp->kso >= ko) 311108558Sphk wp->kso += kp->sectorsize; 312105464Sphk 313108558Sphk if (wp->so >= ko) { 314108558Sphk /* lock sector before work packet */ 315108558Sphk wp->so += kp->sectorsize; 316108558Sphk } else if ((wp->so + wp->length) > ko) { 317108558Sphk /* lock sector in work packet, truncate */ 318108558Sphk wp->length = ko - wp->so; 319108558Sphk } 320108558Sphk } 321108558Sphk 322105464Sphk#if 0 323108558Sphk printf("off %jd len %jd so %jd ko %jd kso %u\n", 324108558Sphk (intmax_t)wp->offset, 325108558Sphk (intmax_t)wp->length, 326108558Sphk (intmax_t)wp->so, 327108558Sphk (intmax_t)wp->kso, 328108558Sphk wp->ko); 329105464Sphk#endif 330105464Sphk} 331