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