1/* $OpenBSD: softraid.c,v 1.7 2024/04/25 18:31:49 kn Exp $ */ 2 3/* 4 * Copyright (c) 2012 Joel Sing <jsing@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/param.h> 20#include <sys/queue.h> 21 22#include <dev/biovar.h> 23#include <dev/softraidvar.h> 24 25#include <lib/libsa/bcrypt_pbkdf.h> 26#include <lib/libsa/hmac_sha1.h> 27#include <lib/libsa/pkcs5_pbkdf2.h> 28#include <lib/libsa/rijndael.h> 29 30#include "stand.h" 31#include "softraid.h" 32 33#define RIJNDAEL128_BLOCK_LEN 16 34#define PASSPHRASE_LENGTH 1024 35 36#define SR_CRYPTO_KEYBLOCK_BYTES SR_CRYPTO_MAXKEYS * SR_CRYPTO_KEYBYTES 37 38/* List of softraid volumes. */ 39struct sr_boot_volume_head sr_volumes; 40 41/* List of softraid keydisks. */ 42struct sr_boot_keydisk_head sr_keydisks; 43 44#ifdef DEBUG 45void 46printhex(const char *s, const u_int8_t *buf, size_t len) 47{ 48 u_int8_t n1, n2; 49 size_t i; 50 51 printf("%s: ", s); 52 for (i = 0; i < len; i++) { 53 n1 = buf[i] & 0x0f; 54 n2 = buf[i] >> 4; 55 printf("%c", n2 > 9 ? n2 + 'a' - 10 : n2 + '0'); 56 printf("%c", n1 > 9 ? n1 + 'a' - 10 : n1 + '0'); 57 } 58 printf("\n"); 59} 60#endif 61 62void 63sr_clear_keys(void) 64{ 65 struct sr_boot_volume *bv; 66 struct sr_boot_keydisk *kd, *nkd; 67 68 SLIST_FOREACH(bv, &sr_volumes, sbv_link) { 69 if (bv->sbv_level != 'C' && bv->sbv_level != 0x1C) 70 continue; 71 if (bv->sbv_keys != NULL) { 72 explicit_bzero(bv->sbv_keys, SR_CRYPTO_KEYBLOCK_BYTES); 73 free(bv->sbv_keys, SR_CRYPTO_KEYBLOCK_BYTES); 74 bv->sbv_keys = NULL; 75 } 76 if (bv->sbv_maskkey != NULL) { 77 explicit_bzero(bv->sbv_maskkey, SR_CRYPTO_MAXKEYBYTES); 78 free(bv->sbv_maskkey, SR_CRYPTO_MAXKEYBYTES); 79 bv->sbv_maskkey = NULL; 80 } 81 } 82 SLIST_FOREACH_SAFE(kd, &sr_keydisks, kd_link, nkd) { 83 explicit_bzero(kd, sizeof(*kd)); 84 free(kd, sizeof(*kd)); 85 } 86} 87 88void 89sr_crypto_calculate_check_hmac_sha1(u_int8_t *maskkey, int maskkey_size, 90 u_int8_t *key, int key_size, u_char *check_digest) 91{ 92 u_int8_t check_key[SHA1_DIGEST_LENGTH]; 93 SHA1_CTX shactx; 94 95 explicit_bzero(check_key, sizeof(check_key)); 96 explicit_bzero(&shactx, sizeof(shactx)); 97 98 /* k = SHA1(mask_key) */ 99 SHA1Init(&shactx); 100 SHA1Update(&shactx, maskkey, maskkey_size); 101 SHA1Final(check_key, &shactx); 102 103 /* mac = HMAC_SHA1_k(unencrypted key) */ 104 hmac_sha1(key, key_size, check_key, sizeof(check_key), check_digest); 105 106 explicit_bzero(check_key, sizeof(check_key)); 107 explicit_bzero(&shactx, sizeof(shactx)); 108} 109 110static int 111sr_crypto_decrypt_keys(struct sr_meta_crypto *cm, 112 struct sr_crypto_kdfinfo *kdfinfo, u_int8_t *kp) 113{ 114 u_int8_t digest[SHA1_DIGEST_LENGTH]; 115 rijndael_ctx ctx; 116 u_int8_t *cp; 117 int rv = -1; 118 int i; 119 120 if (rijndael_set_key(&ctx, kdfinfo->maskkey, 256) != 0) 121 goto done; 122 123 cp = (u_int8_t *)cm->scm_key; 124 for (i = 0; i < SR_CRYPTO_KEYBLOCK_BYTES; i += RIJNDAEL128_BLOCK_LEN) 125 rijndael_decrypt(&ctx, (u_char *)(cp + i), (u_char *)(kp + i)); 126 127 /* Check that the key decrypted properly. */ 128 sr_crypto_calculate_check_hmac_sha1(kdfinfo->maskkey, 129 sizeof(kdfinfo->maskkey), kp, SR_CRYPTO_KEYBLOCK_BYTES, digest); 130 131 if (bcmp(digest, cm->chk_hmac_sha1.sch_mac, sizeof(digest)) == 0) 132 rv = 0; 133 134 done: 135 explicit_bzero(digest, sizeof(digest)); 136 137 return rv; 138} 139 140static int 141sr_crypto_passphrase_decrypt(struct sr_meta_crypto *cm, 142 struct sr_crypto_kdfinfo *kdfinfo, u_int8_t *kp) 143{ 144 char passphrase[PASSPHRASE_LENGTH]; 145 struct sr_crypto_pbkdf *kdfhint; 146 int rv = -1; 147 int c, i; 148 149 kdfhint = (struct sr_crypto_pbkdf *)&cm->scm_kdfhint; 150 151 for (;;) { 152 printf("Passphrase: "); 153#ifdef IDLE_POWEROFF 154extern int idle_poweroff(void); 155 idle_poweroff(); 156#endif /* IDLE_POWEROFF */ 157 for (i = 0; i < PASSPHRASE_LENGTH - 1; i++) { 158 c = cngetc(); 159 if (c == '\r' || c == '\n') { 160 break; 161 } else if (c == '\b') { 162 i = i > 0 ? i - 2 : -1; 163 continue; 164 } 165 passphrase[i] = (c & 0xff); 166 } 167 passphrase[i] = 0; 168 printf("\n"); 169 170 /* Abort on an empty passphrase. */ 171 if (i == 0) { 172 printf("aborting...\n"); 173 goto done; 174 } 175 176#ifdef DEBUG 177 printf("Got passphrase: %s with len %d\n", 178 passphrase, strlen(passphrase)); 179#endif 180 181 switch (kdfhint->generic.type) { 182 case SR_CRYPTOKDFT_PKCS5_PBKDF2: 183 if (pkcs5_pbkdf2(passphrase, strlen(passphrase), 184 kdfhint->salt, sizeof(kdfhint->salt), 185 kdfinfo->maskkey, sizeof(kdfinfo->maskkey), 186 kdfhint->rounds) != 0) { 187 printf("pkcs5_pbkdf2 failed\n"); 188 goto done; 189 } 190 break; 191 192 case SR_CRYPTOKDFT_BCRYPT_PBKDF: 193 if (bcrypt_pbkdf(passphrase, strlen(passphrase), 194 kdfhint->salt, sizeof(kdfhint->salt), 195 kdfinfo->maskkey, sizeof(kdfinfo->maskkey), 196 kdfhint->rounds) != 0) { 197 printf("bcrypt_pbkdf failed\n"); 198 goto done; 199 } 200 break; 201 202 default: 203 printf("unknown KDF type %u\n", kdfhint->generic.type); 204 goto done; 205 } 206 207 if (sr_crypto_decrypt_keys(cm, kdfinfo, kp) == 0) { 208 rv = 0; 209 goto done; 210 } 211 212 printf("incorrect passphrase\n"); 213 } 214 215 done: 216 explicit_bzero(passphrase, PASSPHRASE_LENGTH); 217 218 return rv; 219} 220 221int 222sr_crypto_unlock_volume(struct sr_boot_volume *bv) 223{ 224 struct sr_meta_crypto *cm; 225 struct sr_boot_keydisk *kd; 226 struct sr_meta_opt_item *omi; 227 struct sr_crypto_pbkdf *kdfhint; 228 struct sr_crypto_kdfinfo kdfinfo; 229 u_int8_t *keys = NULL; 230 int rv = -1; 231 232 SLIST_FOREACH(omi, &bv->sbv_meta_opt, omi_link) 233 if (omi->omi_som->som_type == SR_OPT_CRYPTO) 234 break; 235 236 if (omi == NULL) { 237 printf("crypto metadata not found!\n"); 238 goto done; 239 } 240 241 cm = (struct sr_meta_crypto *)omi->omi_som; 242 kdfhint = (struct sr_crypto_pbkdf *)&cm->scm_kdfhint; 243 244 switch (cm->scm_mask_alg) { 245 case SR_CRYPTOM_AES_ECB_256: 246 break; 247 default: 248 printf("unsupported encryption algorithm %u\n", 249 cm->scm_mask_alg); 250 goto done; 251 } 252 253 keys = alloc(SR_CRYPTO_KEYBLOCK_BYTES); 254 bzero(keys, SR_CRYPTO_KEYBLOCK_BYTES); 255 256 switch (kdfhint->generic.type) { 257 case SR_CRYPTOKDFT_KEYDISK: 258 SLIST_FOREACH(kd, &sr_keydisks, kd_link) { 259 if (bcmp(&kd->kd_uuid, &bv->sbv_uuid, 260 sizeof(kd->kd_uuid)) == 0) 261 break; 262 } 263 if (kd == NULL) { 264 printf("keydisk not found\n"); 265 goto done; 266 } 267 bcopy(&kd->kd_key, &kdfinfo.maskkey, sizeof(kdfinfo.maskkey)); 268 if (sr_crypto_decrypt_keys(cm, &kdfinfo, keys) != 0) { 269 printf("incorrect keydisk\n"); 270 goto done; 271 } 272 break; 273 274 case SR_CRYPTOKDFT_BCRYPT_PBKDF: 275 case SR_CRYPTOKDFT_PKCS5_PBKDF2: 276 if (sr_crypto_passphrase_decrypt(cm, &kdfinfo, keys) != 0) 277 goto done; 278 break; 279 280 default: 281 printf("unknown KDF type %u\n", kdfhint->generic.type); 282 goto done; 283 } 284 285 /* Keys and keydisks will be cleared before boot and from _rtt. */ 286 bv->sbv_keys = keys; 287 bv->sbv_maskkey = alloc(sizeof(kdfinfo.maskkey)); 288 bcopy(&kdfinfo.maskkey, bv->sbv_maskkey, sizeof(kdfinfo.maskkey)); 289 290 rv = 0; 291 292 done: 293 explicit_bzero(&kdfinfo, sizeof(kdfinfo)); 294 295 if (keys != NULL && rv != 0) { 296 explicit_bzero(keys, SR_CRYPTO_KEYBLOCK_BYTES); 297 free(keys, SR_CRYPTO_KEYBLOCK_BYTES); 298 } 299 300 return (rv); 301} 302