qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio
at master 532 lines 16 kB view raw
1/* 2 * QEMU Crypto cipher built-in algorithms 3 * 4 * Copyright (c) 2015 Red Hat, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21#include "qemu/osdep.h" 22#include "crypto/aes.h" 23#include "crypto/desrfb.h" 24#include "crypto/xts.h" 25#include "cipherpriv.h" 26 27typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext; 28struct QCryptoCipherBuiltinAESContext { 29 AES_KEY enc; 30 AES_KEY dec; 31}; 32typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES; 33struct QCryptoCipherBuiltinAES { 34 QCryptoCipherBuiltinAESContext key; 35 QCryptoCipherBuiltinAESContext key_tweak; 36 uint8_t iv[AES_BLOCK_SIZE]; 37}; 38typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB; 39struct QCryptoCipherBuiltinDESRFB { 40 uint8_t *key; 41 size_t nkey; 42}; 43 44typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin; 45struct QCryptoCipherBuiltin { 46 union { 47 QCryptoCipherBuiltinAES aes; 48 QCryptoCipherBuiltinDESRFB desrfb; 49 } state; 50 size_t blocksize; 51 void (*free)(QCryptoCipher *cipher); 52 int (*setiv)(QCryptoCipher *cipher, 53 const uint8_t *iv, size_t niv, 54 Error **errp); 55 int (*encrypt)(QCryptoCipher *cipher, 56 const void *in, 57 void *out, 58 size_t len, 59 Error **errp); 60 int (*decrypt)(QCryptoCipher *cipher, 61 const void *in, 62 void *out, 63 size_t len, 64 Error **errp); 65}; 66 67 68static void qcrypto_cipher_free_aes(QCryptoCipher *cipher) 69{ 70 QCryptoCipherBuiltin *ctxt = cipher->opaque; 71 72 g_free(ctxt); 73 cipher->opaque = NULL; 74} 75 76 77static void qcrypto_cipher_aes_ecb_encrypt(const AES_KEY *key, 78 const void *in, 79 void *out, 80 size_t len) 81{ 82 const uint8_t *inptr = in; 83 uint8_t *outptr = out; 84 while (len) { 85 if (len > AES_BLOCK_SIZE) { 86 AES_encrypt(inptr, outptr, key); 87 inptr += AES_BLOCK_SIZE; 88 outptr += AES_BLOCK_SIZE; 89 len -= AES_BLOCK_SIZE; 90 } else { 91 uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE]; 92 memcpy(tmp1, inptr, len); 93 /* Fill with 0 to avoid valgrind uninitialized reads */ 94 memset(tmp1 + len, 0, sizeof(tmp1) - len); 95 AES_encrypt(tmp1, tmp2, key); 96 memcpy(outptr, tmp2, len); 97 len = 0; 98 } 99 } 100} 101 102 103static void qcrypto_cipher_aes_ecb_decrypt(const AES_KEY *key, 104 const void *in, 105 void *out, 106 size_t len) 107{ 108 const uint8_t *inptr = in; 109 uint8_t *outptr = out; 110 while (len) { 111 if (len > AES_BLOCK_SIZE) { 112 AES_decrypt(inptr, outptr, key); 113 inptr += AES_BLOCK_SIZE; 114 outptr += AES_BLOCK_SIZE; 115 len -= AES_BLOCK_SIZE; 116 } else { 117 uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE]; 118 memcpy(tmp1, inptr, len); 119 /* Fill with 0 to avoid valgrind uninitialized reads */ 120 memset(tmp1 + len, 0, sizeof(tmp1) - len); 121 AES_decrypt(tmp1, tmp2, key); 122 memcpy(outptr, tmp2, len); 123 len = 0; 124 } 125 } 126} 127 128 129static void qcrypto_cipher_aes_xts_encrypt(const void *ctx, 130 size_t length, 131 uint8_t *dst, 132 const uint8_t *src) 133{ 134 const QCryptoCipherBuiltinAESContext *aesctx = ctx; 135 136 qcrypto_cipher_aes_ecb_encrypt(&aesctx->enc, src, dst, length); 137} 138 139 140static void qcrypto_cipher_aes_xts_decrypt(const void *ctx, 141 size_t length, 142 uint8_t *dst, 143 const uint8_t *src) 144{ 145 const QCryptoCipherBuiltinAESContext *aesctx = ctx; 146 147 qcrypto_cipher_aes_ecb_decrypt(&aesctx->dec, src, dst, length); 148} 149 150 151static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher, 152 const void *in, 153 void *out, 154 size_t len, 155 Error **errp) 156{ 157 QCryptoCipherBuiltin *ctxt = cipher->opaque; 158 159 switch (cipher->mode) { 160 case QCRYPTO_CIPHER_MODE_ECB: 161 qcrypto_cipher_aes_ecb_encrypt(&ctxt->state.aes.key.enc, 162 in, out, len); 163 break; 164 case QCRYPTO_CIPHER_MODE_CBC: 165 AES_cbc_encrypt(in, out, len, 166 &ctxt->state.aes.key.enc, 167 ctxt->state.aes.iv, 1); 168 break; 169 case QCRYPTO_CIPHER_MODE_XTS: 170 xts_encrypt(&ctxt->state.aes.key, 171 &ctxt->state.aes.key_tweak, 172 qcrypto_cipher_aes_xts_encrypt, 173 qcrypto_cipher_aes_xts_decrypt, 174 ctxt->state.aes.iv, 175 len, out, in); 176 break; 177 default: 178 g_assert_not_reached(); 179 } 180 181 return 0; 182} 183 184 185static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher, 186 const void *in, 187 void *out, 188 size_t len, 189 Error **errp) 190{ 191 QCryptoCipherBuiltin *ctxt = cipher->opaque; 192 193 switch (cipher->mode) { 194 case QCRYPTO_CIPHER_MODE_ECB: 195 qcrypto_cipher_aes_ecb_decrypt(&ctxt->state.aes.key.dec, 196 in, out, len); 197 break; 198 case QCRYPTO_CIPHER_MODE_CBC: 199 AES_cbc_encrypt(in, out, len, 200 &ctxt->state.aes.key.dec, 201 ctxt->state.aes.iv, 0); 202 break; 203 case QCRYPTO_CIPHER_MODE_XTS: 204 xts_decrypt(&ctxt->state.aes.key, 205 &ctxt->state.aes.key_tweak, 206 qcrypto_cipher_aes_xts_encrypt, 207 qcrypto_cipher_aes_xts_decrypt, 208 ctxt->state.aes.iv, 209 len, out, in); 210 break; 211 default: 212 g_assert_not_reached(); 213 } 214 215 return 0; 216} 217 218static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher, 219 const uint8_t *iv, size_t niv, 220 Error **errp) 221{ 222 QCryptoCipherBuiltin *ctxt = cipher->opaque; 223 if (niv != AES_BLOCK_SIZE) { 224 error_setg(errp, "IV must be %d bytes not %zu", 225 AES_BLOCK_SIZE, niv); 226 return -1; 227 } 228 229 memcpy(ctxt->state.aes.iv, iv, AES_BLOCK_SIZE); 230 231 return 0; 232} 233 234 235 236 237static QCryptoCipherBuiltin * 238qcrypto_cipher_init_aes(QCryptoCipherMode mode, 239 const uint8_t *key, size_t nkey, 240 Error **errp) 241{ 242 QCryptoCipherBuiltin *ctxt; 243 244 if (mode != QCRYPTO_CIPHER_MODE_CBC && 245 mode != QCRYPTO_CIPHER_MODE_ECB && 246 mode != QCRYPTO_CIPHER_MODE_XTS) { 247 error_setg(errp, "Unsupported cipher mode %s", 248 QCryptoCipherMode_str(mode)); 249 return NULL; 250 } 251 252 ctxt = g_new0(QCryptoCipherBuiltin, 1); 253 254 if (mode == QCRYPTO_CIPHER_MODE_XTS) { 255 if (AES_set_encrypt_key(key, nkey * 4, &ctxt->state.aes.key.enc) != 0) { 256 error_setg(errp, "Failed to set encryption key"); 257 goto error; 258 } 259 260 if (AES_set_decrypt_key(key, nkey * 4, &ctxt->state.aes.key.dec) != 0) { 261 error_setg(errp, "Failed to set decryption key"); 262 goto error; 263 } 264 265 if (AES_set_encrypt_key(key + (nkey / 2), nkey * 4, 266 &ctxt->state.aes.key_tweak.enc) != 0) { 267 error_setg(errp, "Failed to set encryption key"); 268 goto error; 269 } 270 271 if (AES_set_decrypt_key(key + (nkey / 2), nkey * 4, 272 &ctxt->state.aes.key_tweak.dec) != 0) { 273 error_setg(errp, "Failed to set decryption key"); 274 goto error; 275 } 276 } else { 277 if (AES_set_encrypt_key(key, nkey * 8, &ctxt->state.aes.key.enc) != 0) { 278 error_setg(errp, "Failed to set encryption key"); 279 goto error; 280 } 281 282 if (AES_set_decrypt_key(key, nkey * 8, &ctxt->state.aes.key.dec) != 0) { 283 error_setg(errp, "Failed to set decryption key"); 284 goto error; 285 } 286 } 287 288 ctxt->blocksize = AES_BLOCK_SIZE; 289 ctxt->free = qcrypto_cipher_free_aes; 290 ctxt->setiv = qcrypto_cipher_setiv_aes; 291 ctxt->encrypt = qcrypto_cipher_encrypt_aes; 292 ctxt->decrypt = qcrypto_cipher_decrypt_aes; 293 294 return ctxt; 295 296 error: 297 g_free(ctxt); 298 return NULL; 299} 300 301 302static void qcrypto_cipher_free_des_rfb(QCryptoCipher *cipher) 303{ 304 QCryptoCipherBuiltin *ctxt = cipher->opaque; 305 306 g_free(ctxt->state.desrfb.key); 307 g_free(ctxt); 308 cipher->opaque = NULL; 309} 310 311 312static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher, 313 const void *in, 314 void *out, 315 size_t len, 316 Error **errp) 317{ 318 QCryptoCipherBuiltin *ctxt = cipher->opaque; 319 size_t i; 320 321 if (len % 8) { 322 error_setg(errp, "Buffer size must be multiple of 8 not %zu", 323 len); 324 return -1; 325 } 326 327 deskey(ctxt->state.desrfb.key, EN0); 328 329 for (i = 0; i < len; i += 8) { 330 des((void *)in + i, out + i); 331 } 332 333 return 0; 334} 335 336 337static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher, 338 const void *in, 339 void *out, 340 size_t len, 341 Error **errp) 342{ 343 QCryptoCipherBuiltin *ctxt = cipher->opaque; 344 size_t i; 345 346 if (len % 8) { 347 error_setg(errp, "Buffer size must be multiple of 8 not %zu", 348 len); 349 return -1; 350 } 351 352 deskey(ctxt->state.desrfb.key, DE1); 353 354 for (i = 0; i < len; i += 8) { 355 des((void *)in + i, out + i); 356 } 357 358 return 0; 359} 360 361 362static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher, 363 const uint8_t *iv, size_t niv, 364 Error **errp) 365{ 366 error_setg(errp, "Setting IV is not supported"); 367 return -1; 368} 369 370 371static QCryptoCipherBuiltin * 372qcrypto_cipher_init_des_rfb(QCryptoCipherMode mode, 373 const uint8_t *key, size_t nkey, 374 Error **errp) 375{ 376 QCryptoCipherBuiltin *ctxt; 377 378 if (mode != QCRYPTO_CIPHER_MODE_ECB) { 379 error_setg(errp, "Unsupported cipher mode %s", 380 QCryptoCipherMode_str(mode)); 381 return NULL; 382 } 383 384 ctxt = g_new0(QCryptoCipherBuiltin, 1); 385 386 ctxt->state.desrfb.key = g_new0(uint8_t, nkey); 387 memcpy(ctxt->state.desrfb.key, key, nkey); 388 ctxt->state.desrfb.nkey = nkey; 389 390 ctxt->blocksize = 8; 391 ctxt->free = qcrypto_cipher_free_des_rfb; 392 ctxt->setiv = qcrypto_cipher_setiv_des_rfb; 393 ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb; 394 ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb; 395 396 return ctxt; 397} 398 399 400bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, 401 QCryptoCipherMode mode) 402{ 403 switch (alg) { 404 case QCRYPTO_CIPHER_ALG_DES_RFB: 405 case QCRYPTO_CIPHER_ALG_AES_128: 406 case QCRYPTO_CIPHER_ALG_AES_192: 407 case QCRYPTO_CIPHER_ALG_AES_256: 408 break; 409 default: 410 return false; 411 } 412 413 switch (mode) { 414 case QCRYPTO_CIPHER_MODE_ECB: 415 case QCRYPTO_CIPHER_MODE_CBC: 416 case QCRYPTO_CIPHER_MODE_XTS: 417 return true; 418 case QCRYPTO_CIPHER_MODE_CTR: 419 return false; 420 default: 421 return false; 422 } 423} 424 425 426static QCryptoCipherBuiltin *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, 427 QCryptoCipherMode mode, 428 const uint8_t *key, 429 size_t nkey, 430 Error **errp) 431{ 432 QCryptoCipherBuiltin *ctxt; 433 434 switch (mode) { 435 case QCRYPTO_CIPHER_MODE_ECB: 436 case QCRYPTO_CIPHER_MODE_CBC: 437 case QCRYPTO_CIPHER_MODE_XTS: 438 break; 439 default: 440 error_setg(errp, "Unsupported cipher mode %s", 441 QCryptoCipherMode_str(mode)); 442 return NULL; 443 } 444 445 if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { 446 return NULL; 447 } 448 449 switch (alg) { 450 case QCRYPTO_CIPHER_ALG_DES_RFB: 451 ctxt = qcrypto_cipher_init_des_rfb(mode, key, nkey, errp); 452 break; 453 case QCRYPTO_CIPHER_ALG_AES_128: 454 case QCRYPTO_CIPHER_ALG_AES_192: 455 case QCRYPTO_CIPHER_ALG_AES_256: 456 ctxt = qcrypto_cipher_init_aes(mode, key, nkey, errp); 457 break; 458 default: 459 error_setg(errp, 460 "Unsupported cipher algorithm %s", 461 QCryptoCipherAlgorithm_str(alg)); 462 return NULL; 463 } 464 465 return ctxt; 466} 467 468static void 469qcrypto_builtin_cipher_ctx_free(QCryptoCipher *cipher) 470{ 471 QCryptoCipherBuiltin *ctxt; 472 473 ctxt = cipher->opaque; 474 ctxt->free(cipher); 475} 476 477 478static int 479qcrypto_builtin_cipher_encrypt(QCryptoCipher *cipher, 480 const void *in, 481 void *out, 482 size_t len, 483 Error **errp) 484{ 485 QCryptoCipherBuiltin *ctxt = cipher->opaque; 486 487 if (len % ctxt->blocksize) { 488 error_setg(errp, "Length %zu must be a multiple of block size %zu", 489 len, ctxt->blocksize); 490 return -1; 491 } 492 493 return ctxt->encrypt(cipher, in, out, len, errp); 494} 495 496 497static int 498qcrypto_builtin_cipher_decrypt(QCryptoCipher *cipher, 499 const void *in, 500 void *out, 501 size_t len, 502 Error **errp) 503{ 504 QCryptoCipherBuiltin *ctxt = cipher->opaque; 505 506 if (len % ctxt->blocksize) { 507 error_setg(errp, "Length %zu must be a multiple of block size %zu", 508 len, ctxt->blocksize); 509 return -1; 510 } 511 512 return ctxt->decrypt(cipher, in, out, len, errp); 513} 514 515 516static int 517qcrypto_builtin_cipher_setiv(QCryptoCipher *cipher, 518 const uint8_t *iv, size_t niv, 519 Error **errp) 520{ 521 QCryptoCipherBuiltin *ctxt = cipher->opaque; 522 523 return ctxt->setiv(cipher, iv, niv, errp); 524} 525 526 527static struct QCryptoCipherDriver qcrypto_cipher_lib_driver = { 528 .cipher_encrypt = qcrypto_builtin_cipher_encrypt, 529 .cipher_decrypt = qcrypto_builtin_cipher_decrypt, 530 .cipher_setiv = qcrypto_builtin_cipher_setiv, 531 .cipher_free = qcrypto_builtin_cipher_ctx_free, 532};