qemu/crypto/cipher-nettle.c
<<
>>
Prefs
   1/*
   2 * QEMU Crypto cipher nettle 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 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/xts.h"
  23
  24#include <nettle/nettle-types.h>
  25#include <nettle/aes.h>
  26#include <nettle/des.h>
  27#include <nettle/cbc.h>
  28#include <nettle/cast128.h>
  29#include <nettle/serpent.h>
  30#include <nettle/twofish.h>
  31
  32typedef void (*QCryptoCipherNettleFuncWrapper)(const void *ctx,
  33                                               size_t length,
  34                                               uint8_t *dst,
  35                                               const uint8_t *src);
  36
  37#if CONFIG_NETTLE_VERSION_MAJOR < 3
  38typedef nettle_crypt_func * QCryptoCipherNettleFuncNative;
  39typedef void *       cipher_ctx_t;
  40typedef unsigned     cipher_length_t;
  41
  42#define cast5_set_key cast128_set_key
  43#else
  44typedef nettle_cipher_func * QCryptoCipherNettleFuncNative;
  45typedef const void * cipher_ctx_t;
  46typedef size_t       cipher_length_t;
  47#endif
  48
  49typedef struct QCryptoNettleAES {
  50    struct aes_ctx enc;
  51    struct aes_ctx dec;
  52} QCryptoNettleAES;
  53
  54static void aes_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
  55                               uint8_t *dst, const uint8_t *src)
  56{
  57    const QCryptoNettleAES *aesctx = ctx;
  58    aes_encrypt(&aesctx->enc, length, dst, src);
  59}
  60
  61static void aes_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
  62                               uint8_t *dst, const uint8_t *src)
  63{
  64    const QCryptoNettleAES *aesctx = ctx;
  65    aes_decrypt(&aesctx->dec, length, dst, src);
  66}
  67
  68static void des_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
  69                               uint8_t *dst, const uint8_t *src)
  70{
  71    des_encrypt(ctx, length, dst, src);
  72}
  73
  74static void des_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
  75                               uint8_t *dst, const uint8_t *src)
  76{
  77    des_decrypt(ctx, length, dst, src);
  78}
  79
  80static void cast128_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
  81                                   uint8_t *dst, const uint8_t *src)
  82{
  83    cast128_encrypt(ctx, length, dst, src);
  84}
  85
  86static void cast128_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
  87                                   uint8_t *dst, const uint8_t *src)
  88{
  89    cast128_decrypt(ctx, length, dst, src);
  90}
  91
  92static void serpent_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
  93                                   uint8_t *dst, const uint8_t *src)
  94{
  95    serpent_encrypt(ctx, length, dst, src);
  96}
  97
  98static void serpent_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
  99                                   uint8_t *dst, const uint8_t *src)
 100{
 101    serpent_decrypt(ctx, length, dst, src);
 102}
 103
 104static void twofish_encrypt_native(cipher_ctx_t ctx, cipher_length_t length,
 105                                   uint8_t *dst, const uint8_t *src)
 106{
 107    twofish_encrypt(ctx, length, dst, src);
 108}
 109
 110static void twofish_decrypt_native(cipher_ctx_t ctx, cipher_length_t length,
 111                                   uint8_t *dst, const uint8_t *src)
 112{
 113    twofish_decrypt(ctx, length, dst, src);
 114}
 115
 116static void aes_encrypt_wrapper(const void *ctx, size_t length,
 117                                uint8_t *dst, const uint8_t *src)
 118{
 119    const QCryptoNettleAES *aesctx = ctx;
 120    aes_encrypt(&aesctx->enc, length, dst, src);
 121}
 122
 123static void aes_decrypt_wrapper(const void *ctx, size_t length,
 124                                uint8_t *dst, const uint8_t *src)
 125{
 126    const QCryptoNettleAES *aesctx = ctx;
 127    aes_decrypt(&aesctx->dec, length, dst, src);
 128}
 129
 130static void des_encrypt_wrapper(const void *ctx, size_t length,
 131                                uint8_t *dst, const uint8_t *src)
 132{
 133    des_encrypt(ctx, length, dst, src);
 134}
 135
 136static void des_decrypt_wrapper(const void *ctx, size_t length,
 137                                uint8_t *dst, const uint8_t *src)
 138{
 139    des_decrypt(ctx, length, dst, src);
 140}
 141
 142static void cast128_encrypt_wrapper(const void *ctx, size_t length,
 143                                    uint8_t *dst, const uint8_t *src)
 144{
 145    cast128_encrypt(ctx, length, dst, src);
 146}
 147
 148static void cast128_decrypt_wrapper(const void *ctx, size_t length,
 149                                    uint8_t *dst, const uint8_t *src)
 150{
 151    cast128_decrypt(ctx, length, dst, src);
 152}
 153
 154static void serpent_encrypt_wrapper(const void *ctx, size_t length,
 155                                    uint8_t *dst, const uint8_t *src)
 156{
 157    serpent_encrypt(ctx, length, dst, src);
 158}
 159
 160static void serpent_decrypt_wrapper(const void *ctx, size_t length,
 161                                    uint8_t *dst, const uint8_t *src)
 162{
 163    serpent_decrypt(ctx, length, dst, src);
 164}
 165
 166static void twofish_encrypt_wrapper(const void *ctx, size_t length,
 167                                    uint8_t *dst, const uint8_t *src)
 168{
 169    twofish_encrypt(ctx, length, dst, src);
 170}
 171
 172static void twofish_decrypt_wrapper(const void *ctx, size_t length,
 173                                    uint8_t *dst, const uint8_t *src)
 174{
 175    twofish_decrypt(ctx, length, dst, src);
 176}
 177
 178typedef struct QCryptoCipherNettle QCryptoCipherNettle;
 179struct QCryptoCipherNettle {
 180    /* Primary cipher context for all modes */
 181    void *ctx;
 182    /* Second cipher context for XTS mode only */
 183    void *ctx_tweak;
 184    /* Cipher callbacks for both contexts */
 185    QCryptoCipherNettleFuncNative alg_encrypt_native;
 186    QCryptoCipherNettleFuncNative alg_decrypt_native;
 187    QCryptoCipherNettleFuncWrapper alg_encrypt_wrapper;
 188    QCryptoCipherNettleFuncWrapper alg_decrypt_wrapper;
 189
 190    uint8_t *iv;
 191    size_t blocksize;
 192};
 193
 194bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg)
 195{
 196    switch (alg) {
 197    case QCRYPTO_CIPHER_ALG_DES_RFB:
 198    case QCRYPTO_CIPHER_ALG_AES_128:
 199    case QCRYPTO_CIPHER_ALG_AES_192:
 200    case QCRYPTO_CIPHER_ALG_AES_256:
 201    case QCRYPTO_CIPHER_ALG_CAST5_128:
 202    case QCRYPTO_CIPHER_ALG_SERPENT_128:
 203    case QCRYPTO_CIPHER_ALG_SERPENT_192:
 204    case QCRYPTO_CIPHER_ALG_SERPENT_256:
 205    case QCRYPTO_CIPHER_ALG_TWOFISH_128:
 206    case QCRYPTO_CIPHER_ALG_TWOFISH_192:
 207    case QCRYPTO_CIPHER_ALG_TWOFISH_256:
 208        return true;
 209    default:
 210        return false;
 211    }
 212}
 213
 214
 215QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
 216                                  QCryptoCipherMode mode,
 217                                  const uint8_t *key, size_t nkey,
 218                                  Error **errp)
 219{
 220    QCryptoCipher *cipher;
 221    QCryptoCipherNettle *ctx;
 222    uint8_t *rfbkey;
 223
 224    switch (mode) {
 225    case QCRYPTO_CIPHER_MODE_ECB:
 226    case QCRYPTO_CIPHER_MODE_CBC:
 227    case QCRYPTO_CIPHER_MODE_XTS:
 228        break;
 229    default:
 230        error_setg(errp, "Unsupported cipher mode %d", mode);
 231        return NULL;
 232    }
 233
 234    if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
 235        return NULL;
 236    }
 237
 238    cipher = g_new0(QCryptoCipher, 1);
 239    cipher->alg = alg;
 240    cipher->mode = mode;
 241
 242    ctx = g_new0(QCryptoCipherNettle, 1);
 243
 244    switch (alg) {
 245    case QCRYPTO_CIPHER_ALG_DES_RFB:
 246        ctx->ctx = g_new0(struct des_ctx, 1);
 247        rfbkey = qcrypto_cipher_munge_des_rfb_key(key, nkey);
 248        des_set_key(ctx->ctx, rfbkey);
 249        g_free(rfbkey);
 250
 251        ctx->alg_encrypt_native = des_encrypt_native;
 252        ctx->alg_decrypt_native = des_decrypt_native;
 253        ctx->alg_encrypt_wrapper = des_encrypt_wrapper;
 254        ctx->alg_decrypt_wrapper = des_decrypt_wrapper;
 255
 256        ctx->blocksize = DES_BLOCK_SIZE;
 257        break;
 258
 259    case QCRYPTO_CIPHER_ALG_AES_128:
 260    case QCRYPTO_CIPHER_ALG_AES_192:
 261    case QCRYPTO_CIPHER_ALG_AES_256:
 262        ctx->ctx = g_new0(QCryptoNettleAES, 1);
 263
 264        if (mode == QCRYPTO_CIPHER_MODE_XTS) {
 265            ctx->ctx_tweak = g_new0(QCryptoNettleAES, 1);
 266
 267            nkey /= 2;
 268            aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx)->enc,
 269                                nkey, key);
 270            aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx)->dec,
 271                                nkey, key);
 272
 273            aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx_tweak)->enc,
 274                                nkey, key + nkey);
 275            aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx_tweak)->dec,
 276                                nkey, key + nkey);
 277        } else {
 278            aes_set_encrypt_key(&((QCryptoNettleAES *)ctx->ctx)->enc,
 279                                nkey, key);
 280            aes_set_decrypt_key(&((QCryptoNettleAES *)ctx->ctx)->dec,
 281                                nkey, key);
 282        }
 283
 284        ctx->alg_encrypt_native = aes_encrypt_native;
 285        ctx->alg_decrypt_native = aes_decrypt_native;
 286        ctx->alg_encrypt_wrapper = aes_encrypt_wrapper;
 287        ctx->alg_decrypt_wrapper = aes_decrypt_wrapper;
 288
 289        ctx->blocksize = AES_BLOCK_SIZE;
 290        break;
 291
 292    case QCRYPTO_CIPHER_ALG_CAST5_128:
 293        ctx->ctx = g_new0(struct cast128_ctx, 1);
 294
 295        if (mode == QCRYPTO_CIPHER_MODE_XTS) {
 296            ctx->ctx_tweak = g_new0(struct cast128_ctx, 1);
 297
 298            nkey /= 2;
 299            cast5_set_key(ctx->ctx, nkey, key);
 300            cast5_set_key(ctx->ctx_tweak, nkey, key + nkey);
 301        } else {
 302            cast5_set_key(ctx->ctx, nkey, key);
 303        }
 304
 305        ctx->alg_encrypt_native = cast128_encrypt_native;
 306        ctx->alg_decrypt_native = cast128_decrypt_native;
 307        ctx->alg_encrypt_wrapper = cast128_encrypt_wrapper;
 308        ctx->alg_decrypt_wrapper = cast128_decrypt_wrapper;
 309
 310        ctx->blocksize = CAST128_BLOCK_SIZE;
 311        break;
 312
 313    case QCRYPTO_CIPHER_ALG_SERPENT_128:
 314    case QCRYPTO_CIPHER_ALG_SERPENT_192:
 315    case QCRYPTO_CIPHER_ALG_SERPENT_256:
 316        ctx->ctx = g_new0(struct serpent_ctx, 1);
 317
 318        if (mode == QCRYPTO_CIPHER_MODE_XTS) {
 319            ctx->ctx_tweak = g_new0(struct serpent_ctx, 1);
 320
 321            nkey /= 2;
 322            serpent_set_key(ctx->ctx, nkey, key);
 323            serpent_set_key(ctx->ctx_tweak, nkey, key + nkey);
 324        } else {
 325            serpent_set_key(ctx->ctx, nkey, key);
 326        }
 327
 328        ctx->alg_encrypt_native = serpent_encrypt_native;
 329        ctx->alg_decrypt_native = serpent_decrypt_native;
 330        ctx->alg_encrypt_wrapper = serpent_encrypt_wrapper;
 331        ctx->alg_decrypt_wrapper = serpent_decrypt_wrapper;
 332
 333        ctx->blocksize = SERPENT_BLOCK_SIZE;
 334        break;
 335
 336    case QCRYPTO_CIPHER_ALG_TWOFISH_128:
 337    case QCRYPTO_CIPHER_ALG_TWOFISH_192:
 338    case QCRYPTO_CIPHER_ALG_TWOFISH_256:
 339        ctx->ctx = g_new0(struct twofish_ctx, 1);
 340
 341        if (mode == QCRYPTO_CIPHER_MODE_XTS) {
 342            ctx->ctx_tweak = g_new0(struct twofish_ctx, 1);
 343
 344            nkey /= 2;
 345            twofish_set_key(ctx->ctx, nkey, key);
 346            twofish_set_key(ctx->ctx_tweak, nkey, key + nkey);
 347        } else {
 348            twofish_set_key(ctx->ctx, nkey, key);
 349        }
 350
 351        ctx->alg_encrypt_native = twofish_encrypt_native;
 352        ctx->alg_decrypt_native = twofish_decrypt_native;
 353        ctx->alg_encrypt_wrapper = twofish_encrypt_wrapper;
 354        ctx->alg_decrypt_wrapper = twofish_decrypt_wrapper;
 355
 356        ctx->blocksize = TWOFISH_BLOCK_SIZE;
 357        break;
 358
 359    default:
 360        error_setg(errp, "Unsupported cipher algorithm %d", alg);
 361        goto error;
 362    }
 363
 364    ctx->iv = g_new0(uint8_t, ctx->blocksize);
 365    cipher->opaque = ctx;
 366
 367    return cipher;
 368
 369 error:
 370    g_free(cipher);
 371    g_free(ctx);
 372    return NULL;
 373}
 374
 375
 376void qcrypto_cipher_free(QCryptoCipher *cipher)
 377{
 378    QCryptoCipherNettle *ctx;
 379
 380    if (!cipher) {
 381        return;
 382    }
 383
 384    ctx = cipher->opaque;
 385    g_free(ctx->iv);
 386    g_free(ctx->ctx);
 387    g_free(ctx->ctx_tweak);
 388    g_free(ctx);
 389    g_free(cipher);
 390}
 391
 392
 393int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
 394                           const void *in,
 395                           void *out,
 396                           size_t len,
 397                           Error **errp)
 398{
 399    QCryptoCipherNettle *ctx = cipher->opaque;
 400
 401    if (len % ctx->blocksize) {
 402        error_setg(errp, "Length %zu must be a multiple of block size %zu",
 403                   len, ctx->blocksize);
 404        return -1;
 405    }
 406
 407    switch (cipher->mode) {
 408    case QCRYPTO_CIPHER_MODE_ECB:
 409        ctx->alg_encrypt_wrapper(ctx->ctx, len, out, in);
 410        break;
 411
 412    case QCRYPTO_CIPHER_MODE_CBC:
 413        cbc_encrypt(ctx->ctx, ctx->alg_encrypt_native,
 414                    ctx->blocksize, ctx->iv,
 415                    len, out, in);
 416        break;
 417
 418    case QCRYPTO_CIPHER_MODE_XTS:
 419        xts_encrypt(ctx->ctx, ctx->ctx_tweak,
 420                    ctx->alg_encrypt_wrapper, ctx->alg_encrypt_wrapper,
 421                    ctx->iv, len, out, in);
 422        break;
 423
 424    default:
 425        error_setg(errp, "Unsupported cipher algorithm %d",
 426                   cipher->alg);
 427        return -1;
 428    }
 429    return 0;
 430}
 431
 432
 433int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
 434                           const void *in,
 435                           void *out,
 436                           size_t len,
 437                           Error **errp)
 438{
 439    QCryptoCipherNettle *ctx = cipher->opaque;
 440
 441    if (len % ctx->blocksize) {
 442        error_setg(errp, "Length %zu must be a multiple of block size %zu",
 443                   len, ctx->blocksize);
 444        return -1;
 445    }
 446
 447    switch (cipher->mode) {
 448    case QCRYPTO_CIPHER_MODE_ECB:
 449        ctx->alg_decrypt_wrapper(ctx->ctx, len, out, in);
 450        break;
 451
 452    case QCRYPTO_CIPHER_MODE_CBC:
 453        cbc_decrypt(ctx->ctx, ctx->alg_decrypt_native,
 454                    ctx->blocksize, ctx->iv,
 455                    len, out, in);
 456        break;
 457
 458    case QCRYPTO_CIPHER_MODE_XTS:
 459        if (ctx->blocksize != XTS_BLOCK_SIZE) {
 460            error_setg(errp, "Block size must be %d not %zu",
 461                       XTS_BLOCK_SIZE, ctx->blocksize);
 462            return -1;
 463        }
 464        xts_decrypt(ctx->ctx, ctx->ctx_tweak,
 465                    ctx->alg_encrypt_wrapper, ctx->alg_decrypt_wrapper,
 466                    ctx->iv, len, out, in);
 467        break;
 468
 469    default:
 470        error_setg(errp, "Unsupported cipher algorithm %d",
 471                   cipher->alg);
 472        return -1;
 473    }
 474    return 0;
 475}
 476
 477int qcrypto_cipher_setiv(QCryptoCipher *cipher,
 478                         const uint8_t *iv, size_t niv,
 479                         Error **errp)
 480{
 481    QCryptoCipherNettle *ctx = cipher->opaque;
 482    if (niv != ctx->blocksize) {
 483        error_setg(errp, "Expected IV size %zu not %zu",
 484                   ctx->blocksize, niv);
 485        return -1;
 486    }
 487    memcpy(ctx->iv, iv, niv);
 488    return 0;
 489}
 490