qemu/tests/test-crypto-cipher.c
<<
>>
Prefs
   1/*
   2 * QEMU Crypto cipher 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
  23#include "crypto/init.h"
  24#include "crypto/cipher.h"
  25#include "qapi/error.h"
  26
  27typedef struct QCryptoCipherTestData QCryptoCipherTestData;
  28struct QCryptoCipherTestData {
  29    const char *path;
  30    QCryptoCipherAlgorithm alg;
  31    QCryptoCipherMode mode;
  32    const char *key;
  33    const char *plaintext;
  34    const char *ciphertext;
  35    const char *iv;
  36};
  37
  38/* AES test data comes from appendix F of:
  39 *
  40 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
  41 */
  42static QCryptoCipherTestData test_data[] = {
  43    {
  44        /* NIST F.1.1 ECB-AES128.Encrypt */
  45        .path = "/crypto/cipher/aes-ecb-128",
  46        .alg = QCRYPTO_CIPHER_ALG_AES_128,
  47        .mode = QCRYPTO_CIPHER_MODE_ECB,
  48        .key = "2b7e151628aed2a6abf7158809cf4f3c",
  49        .plaintext =
  50            "6bc1bee22e409f96e93d7e117393172a"
  51            "ae2d8a571e03ac9c9eb76fac45af8e51"
  52            "30c81c46a35ce411e5fbc1191a0a52ef"
  53            "f69f2445df4f9b17ad2b417be66c3710",
  54        .ciphertext =
  55            "3ad77bb40d7a3660a89ecaf32466ef97"
  56            "f5d3d58503b9699de785895a96fdbaaf"
  57            "43b1cd7f598ece23881b00e3ed030688"
  58            "7b0c785e27e8ad3f8223207104725dd4"
  59    },
  60    {
  61        /* NIST F.1.3 ECB-AES192.Encrypt */
  62        .path = "/crypto/cipher/aes-ecb-192",
  63        .alg = QCRYPTO_CIPHER_ALG_AES_192,
  64        .mode = QCRYPTO_CIPHER_MODE_ECB,
  65        .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
  66        .plaintext  =
  67            "6bc1bee22e409f96e93d7e117393172a"
  68            "ae2d8a571e03ac9c9eb76fac45af8e51"
  69            "30c81c46a35ce411e5fbc1191a0a52ef"
  70            "f69f2445df4f9b17ad2b417be66c3710",
  71        .ciphertext =
  72            "bd334f1d6e45f25ff712a214571fa5cc"
  73            "974104846d0ad3ad7734ecb3ecee4eef"
  74            "ef7afd2270e2e60adce0ba2face6444e"
  75            "9a4b41ba738d6c72fb16691603c18e0e"
  76    },
  77    {
  78        /* NIST F.1.5 ECB-AES256.Encrypt */
  79        .path = "/crypto/cipher/aes-ecb-256",
  80        .alg = QCRYPTO_CIPHER_ALG_AES_256,
  81        .mode = QCRYPTO_CIPHER_MODE_ECB,
  82        .key =
  83            "603deb1015ca71be2b73aef0857d7781"
  84            "1f352c073b6108d72d9810a30914dff4",
  85        .plaintext  =
  86            "6bc1bee22e409f96e93d7e117393172a"
  87            "ae2d8a571e03ac9c9eb76fac45af8e51"
  88            "30c81c46a35ce411e5fbc1191a0a52ef"
  89            "f69f2445df4f9b17ad2b417be66c3710",
  90        .ciphertext =
  91            "f3eed1bdb5d2a03c064b5a7e3db181f8"
  92            "591ccb10d410ed26dc5ba74a31362870"
  93            "b6ed21b99ca6f4f9f153e7b1beafed1d"
  94            "23304b7a39f9f3ff067d8d8f9e24ecc7",
  95    },
  96    {
  97        /* NIST F.2.1 CBC-AES128.Encrypt */
  98        .path = "/crypto/cipher/aes-cbc-128",
  99        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 100        .mode = QCRYPTO_CIPHER_MODE_CBC,
 101        .key = "2b7e151628aed2a6abf7158809cf4f3c",
 102        .iv = "000102030405060708090a0b0c0d0e0f",
 103        .plaintext  =
 104            "6bc1bee22e409f96e93d7e117393172a"
 105            "ae2d8a571e03ac9c9eb76fac45af8e51"
 106            "30c81c46a35ce411e5fbc1191a0a52ef"
 107            "f69f2445df4f9b17ad2b417be66c3710",
 108        .ciphertext =
 109            "7649abac8119b246cee98e9b12e9197d"
 110            "5086cb9b507219ee95db113a917678b2"
 111            "73bed6b8e3c1743b7116e69e22229516"
 112            "3ff1caa1681fac09120eca307586e1a7",
 113    },
 114    {
 115        /* NIST F.2.3 CBC-AES128.Encrypt */
 116        .path = "/crypto/cipher/aes-cbc-192",
 117        .alg = QCRYPTO_CIPHER_ALG_AES_192,
 118        .mode = QCRYPTO_CIPHER_MODE_CBC,
 119        .key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
 120        .iv = "000102030405060708090a0b0c0d0e0f",
 121        .plaintext  =
 122            "6bc1bee22e409f96e93d7e117393172a"
 123            "ae2d8a571e03ac9c9eb76fac45af8e51"
 124            "30c81c46a35ce411e5fbc1191a0a52ef"
 125            "f69f2445df4f9b17ad2b417be66c3710",
 126        .ciphertext =
 127            "4f021db243bc633d7178183a9fa071e8"
 128            "b4d9ada9ad7dedf4e5e738763f69145a"
 129            "571b242012fb7ae07fa9baac3df102e0"
 130            "08b0e27988598881d920a9e64f5615cd",
 131    },
 132    {
 133        /* NIST F.2.5 CBC-AES128.Encrypt */
 134        .path = "/crypto/cipher/aes-cbc-256",
 135        .alg = QCRYPTO_CIPHER_ALG_AES_256,
 136        .mode = QCRYPTO_CIPHER_MODE_CBC,
 137        .key =
 138            "603deb1015ca71be2b73aef0857d7781"
 139            "1f352c073b6108d72d9810a30914dff4",
 140        .iv = "000102030405060708090a0b0c0d0e0f",
 141        .plaintext  =
 142            "6bc1bee22e409f96e93d7e117393172a"
 143            "ae2d8a571e03ac9c9eb76fac45af8e51"
 144            "30c81c46a35ce411e5fbc1191a0a52ef"
 145            "f69f2445df4f9b17ad2b417be66c3710",
 146        .ciphertext =
 147            "f58c4c04d6e5f1ba779eabfb5f7bfbd6"
 148            "9cfc4e967edb808d679f777bc6702c7d"
 149            "39f23369a9d9bacfa530e26304231461"
 150            "b2eb05e2c39be9fcda6c19078c6a9d1b",
 151    },
 152    {
 153        .path = "/crypto/cipher/des-rfb-ecb-56",
 154        .alg = QCRYPTO_CIPHER_ALG_DES_RFB,
 155        .mode = QCRYPTO_CIPHER_MODE_ECB,
 156        .key = "0123456789abcdef",
 157        .plaintext =
 158            "6bc1bee22e409f96e93d7e117393172a"
 159            "ae2d8a571e03ac9c9eb76fac45af8e51"
 160            "30c81c46a35ce411e5fbc1191a0a52ef"
 161            "f69f2445df4f9b17ad2b417be66c3710",
 162        .ciphertext =
 163            "8f346aaf64eaf24040720d80648c52e7"
 164            "aefc616be53ab1a3d301e69d91e01838"
 165            "ffd29f1bb5596ad94ea2d8e6196b7f09"
 166            "30d8ed0bf2773af36dd82a6280c20926",
 167    },
 168    {
 169        /* RFC 2144, Appendix B.1 */
 170        .path = "/crypto/cipher/cast5-128",
 171        .alg = QCRYPTO_CIPHER_ALG_CAST5_128,
 172        .mode = QCRYPTO_CIPHER_MODE_ECB,
 173        .key = "0123456712345678234567893456789A",
 174        .plaintext = "0123456789abcdef",
 175        .ciphertext = "238b4fe5847e44b2",
 176    },
 177    {
 178        /* libgcrypt serpent.c */
 179        .path = "/crypto/cipher/serpent-128",
 180        .alg = QCRYPTO_CIPHER_ALG_SERPENT_128,
 181        .mode = QCRYPTO_CIPHER_MODE_ECB,
 182        .key = "00000000000000000000000000000000",
 183        .plaintext = "d29d576fcea3a3a7ed9099f29273d78e",
 184        .ciphertext = "b2288b968ae8b08648d1ce9606fd992d",
 185    },
 186    {
 187        /* libgcrypt serpent.c */
 188        .path = "/crypto/cipher/serpent-192",
 189        .alg = QCRYPTO_CIPHER_ALG_SERPENT_192,
 190        .mode = QCRYPTO_CIPHER_MODE_ECB,
 191        .key = "00000000000000000000000000000000"
 192               "0000000000000000",
 193        .plaintext = "d29d576fceaba3a7ed9899f2927bd78e",
 194        .ciphertext = "130e353e1037c22405e8faefb2c3c3e9",
 195    },
 196    {
 197        /* libgcrypt serpent.c */
 198        .path = "/crypto/cipher/serpent-256a",
 199        .alg = QCRYPTO_CIPHER_ALG_SERPENT_256,
 200        .mode = QCRYPTO_CIPHER_MODE_ECB,
 201        .key = "00000000000000000000000000000000"
 202               "00000000000000000000000000000000",
 203        .plaintext = "d095576fcea3e3a7ed98d9f29073d78e",
 204        .ciphertext = "b90ee5862de69168f2bdd5125b45472b",
 205    },
 206    {
 207        /* libgcrypt serpent.c */
 208        .path = "/crypto/cipher/serpent-256b",
 209        .alg = QCRYPTO_CIPHER_ALG_SERPENT_256,
 210        .mode = QCRYPTO_CIPHER_MODE_ECB,
 211        .key = "00000000000000000000000000000000"
 212               "00000000000000000000000000000000",
 213        .plaintext = "00000000010000000200000003000000",
 214        .ciphertext = "2061a42782bd52ec691ec383b03ba77c",
 215    },
 216    {
 217        /* Twofish paper "Known Answer Test" */
 218        .path = "/crypto/cipher/twofish-128",
 219        .alg = QCRYPTO_CIPHER_ALG_TWOFISH_128,
 220        .mode = QCRYPTO_CIPHER_MODE_ECB,
 221        .key = "d491db16e7b1c39e86cb086b789f5419",
 222        .plaintext = "019f9809de1711858faac3a3ba20fbc3",
 223        .ciphertext = "6363977de839486297e661c6c9d668eb",
 224    },
 225    {
 226        /* Twofish paper "Known Answer Test", I=3 */
 227        .path = "/crypto/cipher/twofish-192",
 228        .alg = QCRYPTO_CIPHER_ALG_TWOFISH_192,
 229        .mode = QCRYPTO_CIPHER_MODE_ECB,
 230        .key = "88b2b2706b105e36b446bb6d731a1e88"
 231               "efa71f788965bd44",
 232        .plaintext = "39da69d6ba4997d585b6dc073ca341b2",
 233        .ciphertext = "182b02d81497ea45f9daacdc29193a65",
 234    },
 235    {
 236        /* Twofish paper "Known Answer Test", I=4 */
 237        .path = "/crypto/cipher/twofish-256",
 238        .alg = QCRYPTO_CIPHER_ALG_TWOFISH_256,
 239        .mode = QCRYPTO_CIPHER_MODE_ECB,
 240        .key = "d43bb7556ea32e46f2a282b7d45b4e0d"
 241               "57ff739d4dc92c1bd7fc01700cc8216f",
 242        .plaintext = "90afe91bb288544f2c32dc239b2635e6",
 243        .ciphertext = "6cb4561c40bf0a9705931cb6d408e7fa",
 244    },
 245    {
 246        /* #1 32 byte key, 32 byte PTX */
 247        .path = "/crypto/cipher/aes-xts-128-1",
 248        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 249        .mode = QCRYPTO_CIPHER_MODE_XTS,
 250        .key =
 251            "00000000000000000000000000000000"
 252            "00000000000000000000000000000000",
 253        .iv =
 254            "00000000000000000000000000000000",
 255        .plaintext =
 256            "00000000000000000000000000000000"
 257            "00000000000000000000000000000000",
 258        .ciphertext =
 259            "917cf69ebd68b2ec9b9fe9a3eadda692"
 260            "cd43d2f59598ed858c02c2652fbf922e",
 261    },
 262    {
 263        /* #2, 32 byte key, 32 byte PTX */
 264        .path = "/crypto/cipher/aes-xts-128-2",
 265        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 266        .mode = QCRYPTO_CIPHER_MODE_XTS,
 267        .key =
 268            "11111111111111111111111111111111"
 269            "22222222222222222222222222222222",
 270        .iv =
 271            "33333333330000000000000000000000",
 272        .plaintext =
 273            "44444444444444444444444444444444"
 274            "44444444444444444444444444444444",
 275        .ciphertext =
 276            "c454185e6a16936e39334038acef838b"
 277            "fb186fff7480adc4289382ecd6d394f0",
 278    },
 279    {
 280        /* #5 from xts.7, 32 byte key, 32 byte PTX */
 281        .path = "/crypto/cipher/aes-xts-128-3",
 282        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 283        .mode = QCRYPTO_CIPHER_MODE_XTS,
 284        .key =
 285            "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0"
 286            "bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0",
 287        .iv =
 288            "9a785634120000000000000000000000",
 289        .plaintext =
 290            "44444444444444444444444444444444"
 291            "44444444444444444444444444444444",
 292        .ciphertext =
 293            "b01f86f8edc1863706fa8a4253e34f28"
 294            "af319de38334870f4dd1f94cbe9832f1",
 295    },
 296    {
 297        /* #4, 32 byte key, 512 byte PTX  */
 298        .path = "/crypto/cipher/aes-xts-128-4",
 299        .alg = QCRYPTO_CIPHER_ALG_AES_128,
 300        .mode = QCRYPTO_CIPHER_MODE_XTS,
 301        .key =
 302            "27182818284590452353602874713526"
 303            "31415926535897932384626433832795",
 304        .iv =
 305            "00000000000000000000000000000000",
 306        .plaintext =
 307            "000102030405060708090a0b0c0d0e0f"
 308            "101112131415161718191a1b1c1d1e1f"
 309            "202122232425262728292a2b2c2d2e2f"
 310            "303132333435363738393a3b3c3d3e3f"
 311            "404142434445464748494a4b4c4d4e4f"
 312            "505152535455565758595a5b5c5d5e5f"
 313            "606162636465666768696a6b6c6d6e6f"
 314            "707172737475767778797a7b7c7d7e7f"
 315            "808182838485868788898a8b8c8d8e8f"
 316            "909192939495969798999a9b9c9d9e9f"
 317            "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
 318            "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
 319            "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
 320            "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
 321            "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
 322            "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"
 323            "000102030405060708090a0b0c0d0e0f"
 324            "101112131415161718191a1b1c1d1e1f"
 325            "202122232425262728292a2b2c2d2e2f"
 326            "303132333435363738393a3b3c3d3e3f"
 327            "404142434445464748494a4b4c4d4e4f"
 328            "505152535455565758595a5b5c5d5e5f"
 329            "606162636465666768696a6b6c6d6e6f"
 330            "707172737475767778797a7b7c7d7e7f"
 331            "808182838485868788898a8b8c8d8e8f"
 332            "909192939495969798999a9b9c9d9e9f"
 333            "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
 334            "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
 335            "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
 336            "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
 337            "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
 338            "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
 339        .ciphertext =
 340            "27a7479befa1d476489f308cd4cfa6e2"
 341            "a96e4bbe3208ff25287dd3819616e89c"
 342            "c78cf7f5e543445f8333d8fa7f560000"
 343            "05279fa5d8b5e4ad40e736ddb4d35412"
 344            "328063fd2aab53e5ea1e0a9f332500a5"
 345            "df9487d07a5c92cc512c8866c7e860ce"
 346            "93fdf166a24912b422976146ae20ce84"
 347            "6bb7dc9ba94a767aaef20c0d61ad0265"
 348            "5ea92dc4c4e41a8952c651d33174be51"
 349            "a10c421110e6d81588ede82103a252d8"
 350            "a750e8768defffed9122810aaeb99f91"
 351            "72af82b604dc4b8e51bcb08235a6f434"
 352            "1332e4ca60482a4ba1a03b3e65008fc5"
 353            "da76b70bf1690db4eae29c5f1badd03c"
 354            "5ccf2a55d705ddcd86d449511ceb7ec3"
 355            "0bf12b1fa35b913f9f747a8afd1b130e"
 356            "94bff94effd01a91735ca1726acd0b19"
 357            "7c4e5b03393697e126826fb6bbde8ecc"
 358            "1e08298516e2c9ed03ff3c1b7860f6de"
 359            "76d4cecd94c8119855ef5297ca67e9f3"
 360            "e7ff72b1e99785ca0a7e7720c5b36dc6"
 361            "d72cac9574c8cbbc2f801e23e56fd344"
 362            "b07f22154beba0f08ce8891e643ed995"
 363            "c94d9a69c9f1b5f499027a78572aeebd"
 364            "74d20cc39881c213ee770b1010e4bea7"
 365            "18846977ae119f7a023ab58cca0ad752"
 366            "afe656bb3c17256a9f6e9bf19fdd5a38"
 367            "fc82bbe872c5539edb609ef4f79c203e"
 368            "bb140f2e583cb2ad15b4aa5b655016a8"
 369            "449277dbd477ef2c8d6c017db738b18d"
 370            "eb4a427d1923ce3ff262735779a418f2"
 371            "0a282df920147beabe421ee5319d0568",
 372    },
 373};
 374
 375
 376static inline int unhex(char c)
 377{
 378    if (c >= 'a' && c <= 'f') {
 379        return 10 + (c - 'a');
 380    }
 381    if (c >= 'A' && c <= 'F') {
 382        return 10 + (c - 'A');
 383    }
 384    return c - '0';
 385}
 386
 387static inline char hex(int i)
 388{
 389    if (i < 10) {
 390        return '0' + i;
 391    }
 392    return 'a' + (i - 10);
 393}
 394
 395static size_t unhex_string(const char *hexstr,
 396                           uint8_t **data)
 397{
 398    size_t len;
 399    size_t i;
 400
 401    if (!hexstr) {
 402        *data = NULL;
 403        return 0;
 404    }
 405
 406    len = strlen(hexstr);
 407    *data = g_new0(uint8_t, len / 2);
 408
 409    for (i = 0; i < len; i += 2) {
 410        (*data)[i/2] = (unhex(hexstr[i]) << 4) | unhex(hexstr[i+1]);
 411    }
 412    return len / 2;
 413}
 414
 415static char *hex_string(const uint8_t *bytes,
 416                        size_t len)
 417{
 418    char *hexstr = g_new0(char, len * 2 + 1);
 419    size_t i;
 420
 421    for (i = 0; i < len; i++) {
 422        hexstr[i*2] = hex((bytes[i] >> 4) & 0xf);
 423        hexstr[i*2+1] = hex(bytes[i] & 0xf);
 424    }
 425    hexstr[len*2] = '\0';
 426
 427    return hexstr;
 428}
 429
 430static void test_cipher(const void *opaque)
 431{
 432    const QCryptoCipherTestData *data = opaque;
 433
 434    QCryptoCipher *cipher;
 435    uint8_t *key, *iv, *ciphertext, *plaintext, *outtext;
 436    size_t nkey, niv, nciphertext, nplaintext;
 437    char *outtexthex;
 438    size_t ivsize, keysize, blocksize;
 439
 440    nkey = unhex_string(data->key, &key);
 441    niv = unhex_string(data->iv, &iv);
 442    nciphertext = unhex_string(data->ciphertext, &ciphertext);
 443    nplaintext = unhex_string(data->plaintext, &plaintext);
 444
 445    g_assert(nciphertext == nplaintext);
 446
 447    outtext = g_new0(uint8_t, nciphertext);
 448
 449    cipher = qcrypto_cipher_new(
 450        data->alg, data->mode,
 451        key, nkey,
 452        &error_abort);
 453    g_assert(cipher != NULL);
 454
 455    keysize = qcrypto_cipher_get_key_len(data->alg);
 456    blocksize = qcrypto_cipher_get_block_len(data->alg);
 457    ivsize = qcrypto_cipher_get_iv_len(data->alg, data->mode);
 458
 459    if (data->mode == QCRYPTO_CIPHER_MODE_XTS) {
 460        g_assert_cmpint(keysize * 2, ==, nkey);
 461    } else {
 462        g_assert_cmpint(keysize, ==, nkey);
 463    }
 464    g_assert_cmpint(ivsize, ==, niv);
 465    if (niv) {
 466        g_assert_cmpint(blocksize, ==, niv);
 467    }
 468
 469    if (iv) {
 470        g_assert(qcrypto_cipher_setiv(cipher,
 471                                      iv, niv,
 472                                      &error_abort) == 0);
 473    }
 474    g_assert(qcrypto_cipher_encrypt(cipher,
 475                                    plaintext,
 476                                    outtext,
 477                                    nplaintext,
 478                                    &error_abort) == 0);
 479
 480    outtexthex = hex_string(outtext, nciphertext);
 481
 482    g_assert_cmpstr(outtexthex, ==, data->ciphertext);
 483
 484    g_free(outtexthex);
 485
 486    if (iv) {
 487        g_assert(qcrypto_cipher_setiv(cipher,
 488                                      iv, niv,
 489                                      &error_abort) == 0);
 490    }
 491    g_assert(qcrypto_cipher_decrypt(cipher,
 492                                    ciphertext,
 493                                    outtext,
 494                                    nplaintext,
 495                                    &error_abort) == 0);
 496
 497    outtexthex = hex_string(outtext, nplaintext);
 498
 499    g_assert_cmpstr(outtexthex, ==, data->plaintext);
 500
 501    g_free(outtext);
 502    g_free(outtexthex);
 503    g_free(key);
 504    g_free(iv);
 505    g_free(ciphertext);
 506    g_free(plaintext);
 507    qcrypto_cipher_free(cipher);
 508}
 509
 510
 511static void test_cipher_null_iv(void)
 512{
 513    QCryptoCipher *cipher;
 514    uint8_t key[32] = { 0 };
 515    uint8_t plaintext[32] = { 0 };
 516    uint8_t ciphertext[32] = { 0 };
 517
 518    cipher = qcrypto_cipher_new(
 519        QCRYPTO_CIPHER_ALG_AES_256,
 520        QCRYPTO_CIPHER_MODE_CBC,
 521        key, sizeof(key),
 522        &error_abort);
 523    g_assert(cipher != NULL);
 524
 525    /* Don't call qcrypto_cipher_setiv */
 526
 527    qcrypto_cipher_encrypt(cipher,
 528                           plaintext,
 529                           ciphertext,
 530                           sizeof(plaintext),
 531                           &error_abort);
 532
 533    qcrypto_cipher_free(cipher);
 534}
 535
 536static void test_cipher_short_plaintext(void)
 537{
 538    Error *err = NULL;
 539    QCryptoCipher *cipher;
 540    uint8_t key[32] = { 0 };
 541    uint8_t plaintext1[20] = { 0 };
 542    uint8_t ciphertext1[20] = { 0 };
 543    uint8_t plaintext2[40] = { 0 };
 544    uint8_t ciphertext2[40] = { 0 };
 545    int ret;
 546
 547    cipher = qcrypto_cipher_new(
 548        QCRYPTO_CIPHER_ALG_AES_256,
 549        QCRYPTO_CIPHER_MODE_CBC,
 550        key, sizeof(key),
 551        &error_abort);
 552    g_assert(cipher != NULL);
 553
 554    /* Should report an error as plaintext is shorter
 555     * than block size
 556     */
 557    ret = qcrypto_cipher_encrypt(cipher,
 558                                 plaintext1,
 559                                 ciphertext1,
 560                                 sizeof(plaintext1),
 561                                 &err);
 562    g_assert(ret == -1);
 563    g_assert(err != NULL);
 564
 565    error_free(err);
 566    err = NULL;
 567
 568    /* Should report an error as plaintext is larger than
 569     * block size, but not a multiple of block size
 570     */
 571    ret = qcrypto_cipher_encrypt(cipher,
 572                                 plaintext2,
 573                                 ciphertext2,
 574                                 sizeof(plaintext2),
 575                                 &err);
 576    g_assert(ret == -1);
 577    g_assert(err != NULL);
 578
 579    error_free(err);
 580    qcrypto_cipher_free(cipher);
 581}
 582
 583int main(int argc, char **argv)
 584{
 585    size_t i;
 586
 587    g_test_init(&argc, &argv, NULL);
 588
 589    g_assert(qcrypto_init(NULL) == 0);
 590
 591    for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
 592        if (qcrypto_cipher_supports(test_data[i].alg)) {
 593            g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
 594        }
 595    }
 596
 597    g_test_add_func("/crypto/cipher/null-iv",
 598                    test_cipher_null_iv);
 599
 600    g_test_add_func("/crypto/cipher/short-plaintext",
 601                    test_cipher_short_plaintext);
 602
 603    return g_test_run();
 604}
 605