Ejemplo n.º 1
0
Archivo: secret.c Proyecto: binape/qemu
static void qcrypto_secret_decode(const uint8_t *input,
                                  size_t inputlen,
                                  uint8_t **output,
                                  size_t *outputlen,
                                  Error **errp)
{
    *output = qbase64_decode((const gchar*)input,
                             inputlen,
                             outputlen,
                             errp);
}
Ejemplo n.º 2
0
static void test_base64_bad(const char *input,
                            size_t input_len)
{
    size_t len;
    Error *err = NULL;
    uint8_t *actual = qbase64_decode(input,
                                     input_len,
                                     &len,
                                     &err);

    g_assert(err != NULL);
    g_assert(actual == NULL);
    g_assert_cmpint(len, ==, 0);
    error_free(err);
}
Ejemplo n.º 3
0
static void test_base64_good(void)
{
    const char input[] =
        "QmVjYXVzZSB3ZSBmb2N1c2VkIG9uIHRoZSBzbmFrZSwgd2UgbW\n"
        "lzc2VkIHRoZSBzY29ycGlvbi4=";
    const char expect[] = "Because we focused on the snake, "
        "we missed the scorpion.";

    size_t len;
    uint8_t *actual = qbase64_decode(input,
                                     -1,
                                     &len,
                                     &error_abort);

    g_assert(actual != NULL);
    g_assert_cmpint(len, ==, strlen(expect));
    g_assert_cmpstr((char *)actual, ==, expect);
    g_free(actual);
}
Ejemplo n.º 4
0
Archivo: secret.c Proyecto: binape/qemu
static void qcrypto_secret_decrypt(QCryptoSecret *secret,
                                   const uint8_t *input,
                                   size_t inputlen,
                                   uint8_t **output,
                                   size_t *outputlen,
                                   Error **errp)
{
    uint8_t *key = NULL, *ciphertext = NULL, *iv = NULL;
    size_t keylen, ciphertextlen, ivlen;
    QCryptoCipher *aes = NULL;
    uint8_t *plaintext = NULL;

    *output = NULL;
    *outputlen = 0;

    if (qcrypto_secret_lookup(secret->keyid,
                              &key, &keylen,
                              errp) < 0) {
        goto cleanup;
    }

    if (keylen != 32) {
        error_setg(errp, "Key should be 32 bytes in length");
        goto cleanup;
    }

    if (!secret->iv) {
        error_setg(errp, "IV is required to decrypt secret");
        goto cleanup;
    }

    iv = qbase64_decode(secret->iv, -1, &ivlen, errp);
    if (!iv) {
        goto cleanup;
    }
    if (ivlen != 16) {
        error_setg(errp, "IV should be 16 bytes in length not %zu",
                   ivlen);
        goto cleanup;
    }

    aes = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256,
                             QCRYPTO_CIPHER_MODE_CBC,
                             key, keylen,
                             errp);
    if (!aes) {
        goto cleanup;
    }

    if (qcrypto_cipher_setiv(aes, iv, ivlen, errp) < 0) {
        goto cleanup;
    }

    if (secret->format == QCRYPTO_SECRET_FORMAT_BASE64) {
        ciphertext = qbase64_decode((const gchar*)input,
                                    inputlen,
                                    &ciphertextlen,
                                    errp);
        if (!ciphertext) {
            goto cleanup;
        }
        plaintext = g_new0(uint8_t, ciphertextlen + 1);
    } else {
        ciphertextlen = inputlen;
        plaintext = g_new0(uint8_t, inputlen + 1);
    }
    if (qcrypto_cipher_decrypt(aes,
                               ciphertext ? ciphertext : input,
                               plaintext,
                               ciphertextlen,
                               errp) < 0) {
        plaintext = NULL;
        goto cleanup;
    }

    if (plaintext[ciphertextlen - 1] > 16 ||
        plaintext[ciphertextlen - 1] > ciphertextlen) {
        error_setg(errp, "Incorrect number of padding bytes (%d) "
                   "found on decrypted data",
                   (int)plaintext[ciphertextlen - 1]);
        g_free(plaintext);
        plaintext = NULL;
        goto cleanup;
    }

    /* Even though plaintext may contain arbitrary NUL
     * ensure it is explicitly NUL terminated.
     */
    ciphertextlen -= plaintext[ciphertextlen - 1];
    plaintext[ciphertextlen] = '\0';

    *output = plaintext;
    *outputlen = ciphertextlen;

 cleanup:
    g_free(ciphertext);
    g_free(iv);
    g_free(key);
    qcrypto_cipher_free(aes);
}