1/*- 2 * Copyright (c) 2002 Poul-Henning Kamp 3 * Copyright (c) 2002 Networks Associates Technology, Inc. 4 * All rights reserved. 5 * 6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp 7 * and NAI Labs, the Security Research Division of Network Associates, Inc. 8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 9 * DARPA CHATS research program. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $FreeBSD: stable/10/sys/geom/bde/g_bde_crypt.c 314327 2017-02-27 08:27:38Z avg $ 33 */ 34/* This source file contains the functions responsible for the crypto, keying 35 * and mapping operations on the I/O requests. 36 * 37 */ 38 39#include <sys/param.h> 40#include <sys/bio.h> 41#include <sys/lock.h> 42#include <sys/mutex.h> 43#include <sys/queue.h> 44#include <sys/malloc.h> 45#include <sys/libkern.h> 46#include <sys/endian.h> 47#include <sys/md5.h> 48 49#include <crypto/rijndael/rijndael-api-fst.h> 50#include <crypto/sha2/sha512.h> 51 52#include <geom/geom.h> 53#include <geom/bde/g_bde.h> 54 55/* 56 * XXX: Debugging DO NOT ENABLE 57 */ 58#undef MD5_KEY 59 60/* 61 * Derive kkey from mkey + sector offset. 62 * 63 * Security objective: Derive a potentially very large number of distinct skeys 64 * from the comparatively small key material in our mkey, in such a way that 65 * if one, more or even many of the kkeys are compromised, this does not 66 * significantly help an attack on other kkeys and in particular does not 67 * weaken or compromise the mkey. 68 * 69 * First we MD5 hash the sectornumber with the salt from the lock sector. 70 * The salt prevents the precalculation and statistical analysis of the MD5 71 * output which would be possible if we only gave it the sectornumber. 72 * 73 * The MD5 hash is used to pick out 16 bytes from the masterkey, which 74 * are then hashed with MD5 together with the sector number. 75 * 76 * The resulting MD5 hash is the kkey. 77 */ 78 79static void 80g_bde_kkey(struct g_bde_softc *sc, keyInstance *ki, int dir, off_t sector) 81{ 82 u_int t; 83 MD5_CTX ct; 84 u_char buf[16]; 85 u_char buf2[8]; 86 87 /* We have to be architecture neutral */ 88 le64enc(buf2, sector); 89 90 MD5Init(&ct); 91 MD5Update(&ct, sc->key.salt, 8); 92 MD5Update(&ct, buf2, sizeof buf2); 93 MD5Update(&ct, sc->key.salt + 8, 8); 94 MD5Final(buf, &ct); 95 96 MD5Init(&ct); 97 for (t = 0; t < 16; t++) { 98 MD5Update(&ct, &sc->key.mkey[buf[t]], 1); 99 if (t == 8) 100 MD5Update(&ct, buf2, sizeof buf2); 101 } 102 bzero(buf2, sizeof buf2); 103 MD5Final(buf, &ct); 104 bzero(&ct, sizeof ct); 105 AES_makekey(ki, dir, G_BDE_KKEYBITS, buf); 106 bzero(buf, sizeof buf); 107} 108 109/* 110 * Encryption work for read operation. 111 * 112 * Security objective: Find the kkey, find the skey, decrypt the sector data. 113 */ 114 115void 116g_bde_crypt_read(struct g_bde_work *wp) 117{ 118 struct g_bde_softc *sc; 119 u_char *d; 120 u_int n; 121 off_t o; 122 u_char skey[G_BDE_SKEYLEN]; 123 keyInstance ki; 124 cipherInstance ci; 125 126 127 AES_init(&ci); 128 sc = wp->softc; 129 o = 0; 130 for (n = 0; o < wp->length; n++, o += sc->sectorsize) { 131 d = (u_char *)wp->ksp->data + wp->ko + n * G_BDE_SKEYLEN; 132 g_bde_kkey(sc, &ki, DIR_DECRYPT, wp->offset + o); 133 AES_decrypt(&ci, &ki, d, skey, sizeof skey); 134 d = (u_char *)wp->data + o; 135 AES_makekey(&ki, DIR_DECRYPT, G_BDE_SKEYBITS, skey); 136 AES_decrypt(&ci, &ki, d, d, sc->sectorsize); 137 } 138 bzero(skey, sizeof skey); 139 bzero(&ci, sizeof ci); 140 bzero(&ki, sizeof ki); 141} 142 143/* 144 * Encryption work for write operation. 145 * 146 * Security objective: Create random skey, encrypt sector data, 147 * encrypt skey with the kkey. 148 */ 149 150void 151g_bde_crypt_write(struct g_bde_work *wp) 152{ 153 u_char *s, *d; 154 struct g_bde_softc *sc; 155 u_int n; 156 off_t o; 157 u_char skey[G_BDE_SKEYLEN]; 158 keyInstance ki; 159 cipherInstance ci; 160 161 sc = wp->softc; 162 AES_init(&ci); 163 o = 0; 164 for (n = 0; o < wp->length; n++, o += sc->sectorsize) { 165 166 s = (u_char *)wp->data + o; 167 d = (u_char *)wp->sp->data + o; 168 arc4rand(skey, sizeof skey, 0); 169 AES_makekey(&ki, DIR_ENCRYPT, G_BDE_SKEYBITS, skey); 170 AES_encrypt(&ci, &ki, s, d, sc->sectorsize); 171 172 d = (u_char *)wp->ksp->data + wp->ko + n * G_BDE_SKEYLEN; 173 g_bde_kkey(sc, &ki, DIR_ENCRYPT, wp->offset + o); 174 AES_encrypt(&ci, &ki, skey, d, sizeof skey); 175 bzero(skey, sizeof skey); 176 } 177 bzero(skey, sizeof skey); 178 bzero(&ci, sizeof ci); 179 bzero(&ki, sizeof ki); 180} 181 182/* 183 * Encryption work for delete operation. 184 * 185 * Security objective: Write random data to the sectors. 186 * 187 * XXX: At a hit in performance we would trash the encrypted skey as well. 188 * XXX: This would add frustration to the cleaning lady attack by making 189 * XXX: deletes look like writes. 190 */ 191 192void 193g_bde_crypt_delete(struct g_bde_work *wp) 194{ 195 struct g_bde_softc *sc; 196 u_char *d; 197 off_t o; 198 u_char skey[G_BDE_SKEYLEN]; 199 keyInstance ki; 200 cipherInstance ci; 201 202 sc = wp->softc; 203 d = wp->sp->data; 204 AES_init(&ci); 205 /* 206 * Do not unroll this loop! 207 * Our zone may be significantly wider than the amount of random 208 * bytes arc4rand likes to give in one reseeding, whereas our 209 * sectorsize is far more likely to be in the same range. 210 */ 211 for (o = 0; o < wp->length; o += sc->sectorsize) { 212 arc4rand(d, sc->sectorsize, 0); 213 arc4rand(skey, sizeof skey, 0); 214 AES_makekey(&ki, DIR_ENCRYPT, G_BDE_SKEYBITS, skey); 215 AES_encrypt(&ci, &ki, d, d, sc->sectorsize); 216 d += sc->sectorsize; 217 } 218 /* 219 * Having written a long random sequence to disk here, we want to 220 * force a reseed, to avoid weakening the next time we use random 221 * data for something important. 222 */ 223 arc4rand(&o, sizeof o, 1); 224} 225 226/* 227 * Calculate the total payload size of the encrypted device. 228 * 229 * Security objectives: none. 230 * 231 * This function needs to agree with g_bde_map_sector() about things. 232 */ 233 234uint64_t 235g_bde_max_sector(struct g_bde_key *kp) 236{ 237 uint64_t maxsect; 238 239 maxsect = kp->media_width; 240 maxsect /= kp->zone_width; 241 maxsect *= kp->zone_cont; 242 return (maxsect); 243} 244 245/* 246 * Convert an unencrypted side offset to offsets on the encrypted side. 247 * 248 * Security objective: Make it harder to identify what sectors contain what 249 * on a "cold" disk image. 250 * 251 * We do this by adding the "keyoffset" from the lock to the physical sector 252 * number modulus the available number of sectors. Since all physical sectors 253 * presumably look the same cold, this will do. 254 * 255 * As part of the mapping we have to skip the lock sectors which we know 256 * the physical address off. We also truncate the work packet, respecting 257 * zone boundaries and lock sectors, so that we end up with a sequence of 258 * sectors which are physically contiguous. 259 * 260 * Shuffling things further is an option, but the incremental frustration is 261 * not currently deemed worth the run-time performance hit resulting from the 262 * increased number of disk arm movements it would incur. 263 * 264 * This function offers nothing but a trivial diversion for an attacker able 265 * to do "the cleaning lady attack" in its current static mapping form. 266 */ 267 268void 269g_bde_map_sector(struct g_bde_work *wp) 270{ 271 272 u_int zone, zoff, u, len; 273 uint64_t ko; 274 struct g_bde_softc *sc; 275 struct g_bde_key *kp; 276 277 sc = wp->softc; 278 kp = &sc->key; 279 280 /* find which zone and the offset in it */ 281 zone = wp->offset / kp->zone_cont; 282 zoff = wp->offset % kp->zone_cont; 283 284 /* Calculate the offset of the key in the key sector */ 285 wp->ko = (zoff / kp->sectorsize) * G_BDE_SKEYLEN; 286 287 /* restrict length to that zone */ 288 len = kp->zone_cont - zoff; 289 290 /* ... and in general */ 291 if (len > DFLTPHYS) 292 len = DFLTPHYS; 293 294 if (len < wp->length) 295 wp->length = len; 296 297 /* Find physical sector address */ 298 wp->so = zone * kp->zone_width + zoff; 299 wp->so += kp->keyoffset; 300 wp->so %= kp->media_width; 301 if (wp->so + wp->length > kp->media_width) 302 wp->length = kp->media_width - wp->so; 303 wp->so += kp->sector0; 304 305 /* The key sector is the last in this zone. */ 306 wp->kso = zone * kp->zone_width + kp->zone_cont; 307 wp->kso += kp->keyoffset; 308 wp->kso %= kp->media_width; 309 wp->kso += kp->sector0; 310 311 /* Compensate for lock sectors */ 312 for (u = 0; u < G_BDE_MAXKEYS; u++) { 313 /* Find the start of this lock sector */ 314 ko = kp->lsector[u] & ~((uint64_t)kp->sectorsize - 1); 315 316 if (wp->kso >= ko) 317 wp->kso += kp->sectorsize; 318 319 if (wp->so >= ko) { 320 /* lock sector before work packet */ 321 wp->so += kp->sectorsize; 322 } else if ((wp->so + wp->length) > ko) { 323 /* lock sector in work packet, truncate */ 324 wp->length = ko - wp->so; 325 } 326 } 327 328#if 0 329 printf("off %jd len %jd so %jd ko %jd kso %u\n", 330 (intmax_t)wp->offset, 331 (intmax_t)wp->length, 332 (intmax_t)wp->so, 333 (intmax_t)wp->kso, 334 wp->ko); 335#endif 336 KASSERT(wp->so + wp->length <= kp->sectorN, 337 ("wp->so (%jd) + wp->length (%jd) > EOM (%jd), offset = %jd", 338 (intmax_t)wp->so, 339 (intmax_t)wp->length, 340 (intmax_t)kp->sectorN, 341 (intmax_t)wp->offset)); 342 343 KASSERT(wp->kso + kp->sectorsize <= kp->sectorN, 344 ("wp->kso (%jd) + kp->sectorsize > EOM (%jd), offset = %jd", 345 (intmax_t)wp->kso, 346 (intmax_t)kp->sectorN, 347 (intmax_t)wp->offset)); 348 349 KASSERT(wp->so >= kp->sector0, 350 ("wp->so (%jd) < BOM (%jd), offset = %jd", 351 (intmax_t)wp->so, 352 (intmax_t)kp->sector0, 353 (intmax_t)wp->offset)); 354 355 KASSERT(wp->kso >= kp->sector0, 356 ("wp->kso (%jd) <BOM (%jd), offset = %jd", 357 (intmax_t)wp->kso, 358 (intmax_t)kp->sector0, 359 (intmax_t)wp->offset)); 360} 361