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 "crypto/aes.h" 22#include "crypto/desrfb.h" 23#include "crypto/xts.h" 24 25typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext; 26struct QCryptoCipherBuiltinAESContext { 27 AES_KEY enc; 28 AES_KEY dec; 29}; 30 31typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES; 32struct QCryptoCipherBuiltinAES { 33 QCryptoCipher base; 34 QCryptoCipherBuiltinAESContext key; 35 QCryptoCipherBuiltinAESContext key_tweak; 36 uint8_t iv[AES_BLOCK_SIZE]; 37}; 38 39 40static inline bool qcrypto_length_check(size_t len, size_t blocksize, 41 Error **errp) 42{ 43 if (unlikely(len & (blocksize - 1))) { 44 error_setg(errp, "Length %zu must be a multiple of block size %zu", 45 len, blocksize); 46 return false; 47 } 48 return true; 49} 50 51static void qcrypto_cipher_ctx_free(QCryptoCipher *cipher) 52{ 53 g_free(cipher); 54} 55 56static int qcrypto_cipher_no_setiv(QCryptoCipher *cipher, 57 const uint8_t *iv, size_t niv, 58 Error **errp) 59{ 60 error_setg(errp, "Setting IV is not supported"); 61 return -1; 62} 63 64static void do_aes_encrypt_ecb(const void *vctx, 65 size_t len, 66 uint8_t *out, 67 const uint8_t *in) 68{ 69 const QCryptoCipherBuiltinAESContext *ctx = vctx; 70 71 /* We have already verified that len % AES_BLOCK_SIZE == 0. */ 72 while (len) { 73 AES_encrypt(in, out, &ctx->enc); 74 in += AES_BLOCK_SIZE; 75 out += AES_BLOCK_SIZE; 76 len -= AES_BLOCK_SIZE; 77 } 78} 79 80static void do_aes_decrypt_ecb(const void *vctx, 81 size_t len, 82 uint8_t *out, 83 const uint8_t *in) 84{ 85 const QCryptoCipherBuiltinAESContext *ctx = vctx; 86 87 /* We have already verified that len % AES_BLOCK_SIZE == 0. */ 88 while (len) { 89 AES_decrypt(in, out, &ctx->dec); 90 in += AES_BLOCK_SIZE; 91 out += AES_BLOCK_SIZE; 92 len -= AES_BLOCK_SIZE; 93 } 94} 95 96static void do_aes_encrypt_cbc(const AES_KEY *key, 97 size_t len, 98 uint8_t *out, 99 const uint8_t *in, 100 uint8_t *ivec) 101{ 102 uint8_t tmp[AES_BLOCK_SIZE]; 103 size_t n; 104 105 /* We have already verified that len % AES_BLOCK_SIZE == 0. */ 106 while (len) { 107 for (n = 0; n < AES_BLOCK_SIZE; ++n) { 108 tmp[n] = in[n] ^ ivec[n]; 109 } 110 AES_encrypt(tmp, out, key); 111 memcpy(ivec, out, AES_BLOCK_SIZE); 112 len -= AES_BLOCK_SIZE; 113 in += AES_BLOCK_SIZE; 114 out += AES_BLOCK_SIZE; 115 } 116} 117 118static void do_aes_decrypt_cbc(const AES_KEY *key, 119 size_t len, 120 uint8_t *out, 121 const uint8_t *in, 122 uint8_t *ivec) 123{ 124 uint8_t tmp[AES_BLOCK_SIZE]; 125 size_t n; 126 127 /* We have already verified that len % AES_BLOCK_SIZE == 0. */ 128 while (len) { 129 memcpy(tmp, in, AES_BLOCK_SIZE); 130 AES_decrypt(in, out, key); 131 for (n = 0; n < AES_BLOCK_SIZE; ++n) { 132 out[n] ^= ivec[n]; 133 } 134 memcpy(ivec, tmp, AES_BLOCK_SIZE); 135 len -= AES_BLOCK_SIZE; 136 in += AES_BLOCK_SIZE; 137 out += AES_BLOCK_SIZE; 138 } 139} 140 141static int qcrypto_cipher_aes_encrypt_ecb(QCryptoCipher *cipher, 142 const void *in, void *out, 143 size_t len, Error **errp) 144{ 145 QCryptoCipherBuiltinAES *ctx 146 = container_of(cipher, QCryptoCipherBuiltinAES, base); 147 148 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { 149 return -1; 150 } 151 do_aes_encrypt_ecb(&ctx->key, len, out, in); 152 return 0; 153} 154 155static int qcrypto_cipher_aes_decrypt_ecb(QCryptoCipher *cipher, 156 const void *in, void *out, 157 size_t len, Error **errp) 158{ 159 QCryptoCipherBuiltinAES *ctx 160 = container_of(cipher, QCryptoCipherBuiltinAES, base); 161 162 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { 163 return -1; 164 } 165 do_aes_decrypt_ecb(&ctx->key, len, out, in); 166 return 0; 167} 168 169static int qcrypto_cipher_aes_encrypt_cbc(QCryptoCipher *cipher, 170 const void *in, void *out, 171 size_t len, Error **errp) 172{ 173 QCryptoCipherBuiltinAES *ctx 174 = container_of(cipher, QCryptoCipherBuiltinAES, base); 175 176 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { 177 return -1; 178 } 179 do_aes_encrypt_cbc(&ctx->key.enc, len, out, in, ctx->iv); 180 return 0; 181} 182 183static int qcrypto_cipher_aes_decrypt_cbc(QCryptoCipher *cipher, 184 const void *in, void *out, 185 size_t len, Error **errp) 186{ 187 QCryptoCipherBuiltinAES *ctx 188 = container_of(cipher, QCryptoCipherBuiltinAES, base); 189 190 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { 191 return -1; 192 } 193 do_aes_decrypt_cbc(&ctx->key.dec, len, out, in, ctx->iv); 194 return 0; 195} 196 197static int qcrypto_cipher_aes_encrypt_xts(QCryptoCipher *cipher, 198 const void *in, void *out, 199 size_t len, Error **errp) 200{ 201 QCryptoCipherBuiltinAES *ctx 202 = container_of(cipher, QCryptoCipherBuiltinAES, base); 203 204 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { 205 return -1; 206 } 207 xts_encrypt(&ctx->key, &ctx->key_tweak, 208 do_aes_encrypt_ecb, do_aes_decrypt_ecb, 209 ctx->iv, len, out, in); 210 return 0; 211} 212 213static int qcrypto_cipher_aes_decrypt_xts(QCryptoCipher *cipher, 214 const void *in, void *out, 215 size_t len, Error **errp) 216{ 217 QCryptoCipherBuiltinAES *ctx 218 = container_of(cipher, QCryptoCipherBuiltinAES, base); 219 220 if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) { 221 return -1; 222 } 223 xts_decrypt(&ctx->key, &ctx->key_tweak, 224 do_aes_encrypt_ecb, do_aes_decrypt_ecb, 225 ctx->iv, len, out, in); 226 return 0; 227} 228 229 230static int qcrypto_cipher_aes_setiv(QCryptoCipher *cipher, const uint8_t *iv, 231 size_t niv, Error **errp) 232{ 233 QCryptoCipherBuiltinAES *ctx 234 = container_of(cipher, QCryptoCipherBuiltinAES, base); 235 236 if (niv != AES_BLOCK_SIZE) { 237 error_setg(errp, "IV must be %d bytes not %zu", 238 AES_BLOCK_SIZE, niv); 239 return -1; 240 } 241 242 memcpy(ctx->iv, iv, AES_BLOCK_SIZE); 243 return 0; 244} 245 246static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_ecb = { 247 .cipher_encrypt = qcrypto_cipher_aes_encrypt_ecb, 248 .cipher_decrypt = qcrypto_cipher_aes_decrypt_ecb, 249 .cipher_setiv = qcrypto_cipher_no_setiv, 250 .cipher_free = qcrypto_cipher_ctx_free, 251}; 252 253static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_cbc = { 254 .cipher_encrypt = qcrypto_cipher_aes_encrypt_cbc, 255 .cipher_decrypt = qcrypto_cipher_aes_decrypt_cbc, 256 .cipher_setiv = qcrypto_cipher_aes_setiv, 257 .cipher_free = qcrypto_cipher_ctx_free, 258}; 259 260static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_xts = { 261 .cipher_encrypt = qcrypto_cipher_aes_encrypt_xts, 262 .cipher_decrypt = qcrypto_cipher_aes_decrypt_xts, 263 .cipher_setiv = qcrypto_cipher_aes_setiv, 264 .cipher_free = qcrypto_cipher_ctx_free, 265}; 266 267 268typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB; 269struct QCryptoCipherBuiltinDESRFB { 270 QCryptoCipher base; 271 272 /* C.f. alg_key_len[QCRYPTO_CIPHER_ALG_DES_RFB] */ 273 uint8_t key[8]; 274}; 275 276static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher, 277 const void *in, void *out, 278 size_t len, Error **errp) 279{ 280 QCryptoCipherBuiltinDESRFB *ctx 281 = container_of(cipher, QCryptoCipherBuiltinDESRFB, base); 282 size_t i; 283 284 if (!qcrypto_length_check(len, 8, errp)) { 285 return -1; 286 } 287 288 deskey(ctx->key, EN0); 289 290 for (i = 0; i < len; i += 8) { 291 des((void *)in + i, out + i); 292 } 293 294 return 0; 295} 296 297static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher, 298 const void *in, void *out, 299 size_t len, Error **errp) 300{ 301 QCryptoCipherBuiltinDESRFB *ctx 302 = container_of(cipher, QCryptoCipherBuiltinDESRFB, base); 303 size_t i; 304 305 if (!qcrypto_length_check(len, 8, errp)) { 306 return -1; 307 } 308 309 deskey(ctx->key, DE1); 310 311 for (i = 0; i < len; i += 8) { 312 des((void *)in + i, out + i); 313 } 314 315 return 0; 316} 317 318static const struct QCryptoCipherDriver qcrypto_cipher_des_rfb_driver = { 319 .cipher_encrypt = qcrypto_cipher_encrypt_des_rfb, 320 .cipher_decrypt = qcrypto_cipher_decrypt_des_rfb, 321 .cipher_setiv = qcrypto_cipher_no_setiv, 322 .cipher_free = qcrypto_cipher_ctx_free, 323}; 324 325bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg, 326 QCryptoCipherMode mode) 327{ 328 switch (alg) { 329 case QCRYPTO_CIPHER_ALG_DES_RFB: 330 return mode == QCRYPTO_CIPHER_MODE_ECB; 331 case QCRYPTO_CIPHER_ALG_AES_128: 332 case QCRYPTO_CIPHER_ALG_AES_192: 333 case QCRYPTO_CIPHER_ALG_AES_256: 334 switch (mode) { 335 case QCRYPTO_CIPHER_MODE_ECB: 336 case QCRYPTO_CIPHER_MODE_CBC: 337 case QCRYPTO_CIPHER_MODE_XTS: 338 return true; 339 default: 340 return false; 341 } 342 break; 343 default: 344 return false; 345 } 346} 347 348static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg, 349 QCryptoCipherMode mode, 350 const uint8_t *key, 351 size_t nkey, 352 Error **errp) 353{ 354 if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) { 355 return NULL; 356 } 357 358 switch (alg) { 359 case QCRYPTO_CIPHER_ALG_DES_RFB: 360 if (mode == QCRYPTO_CIPHER_MODE_ECB) { 361 QCryptoCipherBuiltinDESRFB *ctx; 362 363 ctx = g_new0(QCryptoCipherBuiltinDESRFB, 1); 364 ctx->base.driver = &qcrypto_cipher_des_rfb_driver; 365 memcpy(ctx->key, key, sizeof(ctx->key)); 366 367 return &ctx->base; 368 } 369 goto bad_mode; 370 371 case QCRYPTO_CIPHER_ALG_AES_128: 372 case QCRYPTO_CIPHER_ALG_AES_192: 373 case QCRYPTO_CIPHER_ALG_AES_256: 374 { 375 QCryptoCipherBuiltinAES *ctx; 376 const QCryptoCipherDriver *drv; 377 378 switch (mode) { 379 case QCRYPTO_CIPHER_MODE_ECB: 380 drv = &qcrypto_cipher_aes_driver_ecb; 381 break; 382 case QCRYPTO_CIPHER_MODE_CBC: 383 drv = &qcrypto_cipher_aes_driver_cbc; 384 break; 385 case QCRYPTO_CIPHER_MODE_XTS: 386 drv = &qcrypto_cipher_aes_driver_xts; 387 break; 388 default: 389 goto bad_mode; 390 } 391 392 ctx = g_new0(QCryptoCipherBuiltinAES, 1); 393 ctx->base.driver = drv; 394 395 if (mode == QCRYPTO_CIPHER_MODE_XTS) { 396 nkey /= 2; 397 if (AES_set_encrypt_key(key + nkey, nkey * 8, 398 &ctx->key_tweak.enc)) { 399 error_setg(errp, "Failed to set encryption key"); 400 goto error; 401 } 402 if (AES_set_decrypt_key(key + nkey, nkey * 8, 403 &ctx->key_tweak.dec)) { 404 error_setg(errp, "Failed to set decryption key"); 405 goto error; 406 } 407 } 408 if (AES_set_encrypt_key(key, nkey * 8, &ctx->key.enc)) { 409 error_setg(errp, "Failed to set encryption key"); 410 goto error; 411 } 412 if (AES_set_decrypt_key(key, nkey * 8, &ctx->key.dec)) { 413 error_setg(errp, "Failed to set decryption key"); 414 goto error; 415 } 416 417 return &ctx->base; 418 419 error: 420 g_free(ctx); 421 return NULL; 422 } 423 424 default: 425 error_setg(errp, 426 "Unsupported cipher algorithm %s", 427 QCryptoCipherAlgorithm_str(alg)); 428 return NULL; 429 } 430 431 bad_mode: 432 error_setg(errp, "Unsupported cipher mode %s", 433 QCryptoCipherMode_str(mode)); 434 return NULL; 435} 436