Exemplo n.º 1
0
int cf_ccm_decrypt(const cf_prp *prp, void *prpctx,
                   const uint8_t *cipher, size_t ncipher, size_t L,
                   const uint8_t *header, size_t nheader,
                   const uint8_t *nonce, size_t nnonce,
                   const uint8_t *tag, size_t ntag,
                   uint8_t *plain)
{
    uint8_t block[CF_MAXBLOCK];

    assert(ntag >= 4 && ntag <= 16 && ntag % 2 == 0);
    assert(L >= 2 && L <= 8);
    assert(nnonce == prp->blocksz - L - 1);

    uint8_t ctr_nonce[CF_MAXBLOCK];
    build_ctr_nonce(ctr_nonce, L, nonce, nnonce);

    cf_ctr ctr;
    cf_ctr_init(&ctr, prp, prpctx, ctr_nonce);
    cf_ctr_custom_counter(&ctr, prp->blocksz - L, L);

    /* Decrypt tag. */
    uint8_t plain_tag[CF_MAXBLOCK];
    cf_ctr_cipher(&ctr, tag, plain_tag, ntag);
    cf_ctr_discard_block(&ctr);

    /* Decrypt message. */
    cf_ctr_cipher(&ctr, cipher, plain, ncipher);

    cf_cbcmac_stream cm;
    cf_cbcmac_stream_init(&cm, prp, prpctx);

    /* Add first block. */
    add_block0(&cm, block, prp->blocksz,
               nonce, nnonce,
               L, ncipher, nheader, ntag);

    if (nheader)
        add_aad(&cm, block, header, nheader);

    cf_cbcmac_stream_update(&cm, plain, ncipher);
    zero_pad(&cm);

    /* Finish tag. */
    cf_cbcmac_stream_nopad_final(&cm, block);

    int err = 0;

    if (!mem_eq(block, plain_tag, ntag))
    {
        err = 1;
        mem_clean(plain, ncipher);
    }

    mem_clean(block, sizeof block);
    mem_clean(plain_tag, sizeof plain_tag);
    return err;
}
Exemplo n.º 2
0
void cf_ccm_encrypt(const cf_prp *prp, void *prpctx,
                    const uint8_t *plain, size_t nplain, size_t L,
                    const uint8_t *header, size_t nheader,
                    const uint8_t *nonce, size_t nnonce,
                    uint8_t *cipher,
                    uint8_t *tag, size_t ntag)
{
    uint8_t block[CF_MAXBLOCK];

    assert(ntag >= 4 && ntag <= 16 && ntag % 2 == 0);
    assert(L >= 2 && L <= 8);
    assert(nnonce == prp->blocksz - L - 1);

    cf_cbcmac_stream cm;
    cf_cbcmac_stream_init(&cm, prp, prpctx);

    /* Add first block. */
    add_block0(&cm, block, prp->blocksz,
               nonce, nnonce,
               L, nplain, nheader, ntag);

    /* Add AAD with length prefix, if present. */
    if (nheader)
        add_aad(&cm, block, header, nheader);

    /* Add message. */
    cf_cbcmac_stream_update(&cm, plain, nplain);
    zero_pad(&cm);

    /* Finish tag. */
    cf_cbcmac_stream_nopad_final(&cm, block);

    /* Start encryption. */
    /* Construct A_0 */
    uint8_t ctr_nonce[CF_MAXBLOCK];
    build_ctr_nonce(ctr_nonce, L, nonce, nnonce);

    cf_ctr ctr;
    cf_ctr_init(&ctr, prp, prpctx, ctr_nonce);
    cf_ctr_custom_counter(&ctr, prp->blocksz - L, L);

    /* Encrypt tag first. */
    cf_ctr_cipher(&ctr, block, block, prp->blocksz);
    memcpy(tag, block, ntag);

    /* Then encrypt message. */
    cf_ctr_cipher(&ctr, plain, cipher, nplain);
}
Exemplo n.º 3
0
static void test_ctr(void)
{
    uint8_t out[16];

    const void *nonce = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
    const void *key = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c";
    const void *inp = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a";
    const void *expect = "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce";

    cf_aes_context aes;
    cf_aes_init(&aes, key, 16);

    cf_ctr ctr;
    cf_ctr_init(&ctr, &cf_aes, &aes, nonce);
    cf_ctr_cipher(&ctr, inp, out, 16); /* one piece */
    TEST_CHECK(memcmp(expect, out, 16) == 0);

    cf_ctr_init(&ctr, &cf_aes, &aes, nonce);
    cf_ctr_cipher(&ctr, inp, out, 1); /* incremental (2 blocks) */
    cf_ctr_cipher(&ctr, inp, out, 16);
    cf_ctr_cipher(&ctr, inp, out, 16);

    cf_ctr_init(&ctr, &cf_aes, &aes, nonce);
    cf_ctr_cipher(&ctr, inp, out, 1); /* incremental */
    cf_ctr_cipher(&ctr, inp + 1, out + 1, 15);
    TEST_CHECK(memcmp(expect, out, 16) == 0);

    uint8_t decrypt[16];
    cf_ctr_init(&ctr, &cf_aes, &aes, nonce);
    cf_ctr_cipher(&ctr, out, decrypt, 16);
    TEST_CHECK(memcmp(decrypt, inp, 16) == 0);

    /* Test we use the right number of blocks up. */
    uint8_t test_nonce[16], test_inp[16];
    memset(test_nonce, 0xff, 16);
    memset(test_inp, 0x00, 16);
    cf_ctr_init(&ctr, &cf_aes, &aes, test_nonce);

    /* Exercise cf_blockwise_xor code paths. */
    for (int i = 0; i < 1024; i++)
    {
        cf_ctr_cipher(&ctr, test_inp, out, i % 16);
    }

    /* expected counter value is 1024 * 7.5 / 16 - 1:
     * 479 = 0x1df
     */

    memset(test_nonce, 0, sizeof test_nonce);
    test_nonce[15] = 0xdf;
    test_nonce[14] = 0x01;

    TEST_CHECK(memcmp(test_nonce, ctr.nonce, 16) == 0);
}
Exemplo n.º 4
0
Arquivo: cifra.c Projeto: devnexen/h2o
static void aesctr_transform(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len)
{
    struct aesctr_context_t *ctx = (struct aesctr_context_t *)_ctx;
    cf_ctr_cipher(&ctx->ctr, input, output, len);
}