Blame demos/evp/aesccm.c

Packit Service 084de1
/*
Packit Service 084de1
 * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
Packit Service 084de1
 *
Packit Service 084de1
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit Service 084de1
 * this file except in compliance with the License.  You can obtain a copy
Packit Service 084de1
 * in the file LICENSE in the source distribution or at
Packit Service 084de1
 * https://www.openssl.org/source/license.html
Packit Service 084de1
 */
Packit Service 084de1
Packit Service 084de1
/*
Packit Service 084de1
 * Simple AES CCM test program, uses the same NIST data used for the FIPS
Packit Service 084de1
 * self test but uses the application level EVP APIs.
Packit Service 084de1
 */
Packit Service 084de1
#include <stdio.h>
Packit Service 084de1
#include <openssl/bio.h>
Packit Service 084de1
#include <openssl/evp.h>
Packit Service 084de1
Packit Service 084de1
/* AES-CCM test data from NIST public test vectors */
Packit Service 084de1
Packit Service 084de1
static const unsigned char ccm_key[] = {
Packit Service 084de1
    0xce, 0xb0, 0x09, 0xae, 0xa4, 0x45, 0x44, 0x51, 0xfe, 0xad, 0xf0, 0xe6,
Packit Service 084de1
    0xb3, 0x6f, 0x45, 0x55, 0x5d, 0xd0, 0x47, 0x23, 0xba, 0xa4, 0x48, 0xe8
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
static const unsigned char ccm_nonce[] = {
Packit Service 084de1
    0x76, 0x40, 0x43, 0xc4, 0x94, 0x60, 0xb7
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
static const unsigned char ccm_adata[] = {
Packit Service 084de1
    0x6e, 0x80, 0xdd, 0x7f, 0x1b, 0xad, 0xf3, 0xa1, 0xc9, 0xab, 0x25, 0xc7,
Packit Service 084de1
    0x5f, 0x10, 0xbd, 0xe7, 0x8c, 0x23, 0xfa, 0x0e, 0xb8, 0xf9, 0xaa, 0xa5,
Packit Service 084de1
    0x3a, 0xde, 0xfb, 0xf4, 0xcb, 0xf7, 0x8f, 0xe4
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
static const unsigned char ccm_pt[] = {
Packit Service 084de1
    0xc8, 0xd2, 0x75, 0xf9, 0x19, 0xe1, 0x7d, 0x7f, 0xe6, 0x9c, 0x2a, 0x1f,
Packit Service 084de1
    0x58, 0x93, 0x9d, 0xfe, 0x4d, 0x40, 0x37, 0x91, 0xb5, 0xdf, 0x13, 0x10
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
static const unsigned char ccm_ct[] = {
Packit Service 084de1
    0x8a, 0x0f, 0x3d, 0x82, 0x29, 0xe4, 0x8e, 0x74, 0x87, 0xfd, 0x95, 0xa2,
Packit Service 084de1
    0x8a, 0xd3, 0x92, 0xc8, 0x0b, 0x36, 0x81, 0xd4, 0xfb, 0xc7, 0xbb, 0xfd
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
static const unsigned char ccm_tag[] = {
Packit Service 084de1
    0x2d, 0xd6, 0xef, 0x1c, 0x45, 0xd4, 0xcc, 0xb7, 0x23, 0xdc, 0x07, 0x44,
Packit Service 084de1
    0x14, 0xdb, 0x50, 0x6d
Packit Service 084de1
};
Packit Service 084de1
Packit Service 084de1
void aes_ccm_encrypt(void)
Packit Service 084de1
{
Packit Service 084de1
    EVP_CIPHER_CTX *ctx;
Packit Service 084de1
    int outlen, tmplen;
Packit Service 084de1
    unsigned char outbuf[1024];
Packit Service 084de1
    printf("AES CCM Encrypt:\n");
Packit Service 084de1
    printf("Plaintext:\n");
Packit Service 084de1
    BIO_dump_fp(stdout, ccm_pt, sizeof(ccm_pt));
Packit Service 084de1
    ctx = EVP_CIPHER_CTX_new();
Packit Service 084de1
    /* Set cipher type and mode */
Packit Service 084de1
    EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL);
Packit Service 084de1
    /* Set nonce length if default 96 bits is not appropriate */
Packit Service 084de1
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(ccm_nonce),
Packit Service 084de1
                        NULL);
Packit Service 084de1
    /* Set tag length */
Packit Service 084de1
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(ccm_tag), NULL);
Packit Service 084de1
    /* Initialise key and IV */
Packit Service 084de1
    EVP_EncryptInit_ex(ctx, NULL, NULL, ccm_key, ccm_nonce);
Packit Service 084de1
    /* Set plaintext length: only needed if AAD is used */
Packit Service 084de1
    EVP_EncryptUpdate(ctx, NULL, &outlen, NULL, sizeof(ccm_pt));
Packit Service 084de1
    /* Zero or one call to specify any AAD */
Packit Service 084de1
    EVP_EncryptUpdate(ctx, NULL, &outlen, ccm_adata, sizeof(ccm_adata));
Packit Service 084de1
    /* Encrypt plaintext: can only be called once */
Packit Service 084de1
    EVP_EncryptUpdate(ctx, outbuf, &outlen, ccm_pt, sizeof(ccm_pt));
Packit Service 084de1
    /* Output encrypted block */
Packit Service 084de1
    printf("Ciphertext:\n");
Packit Service 084de1
    BIO_dump_fp(stdout, outbuf, outlen);
Packit Service 084de1
    /* Finalise: note get no output for CCM */
Packit Service 084de1
    EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
Packit Service 084de1
    /* Get tag */
Packit Service 084de1
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outbuf);
Packit Service 084de1
    /* Output tag */
Packit Service 084de1
    printf("Tag:\n");
Packit Service 084de1
    BIO_dump_fp(stdout, outbuf, 16);
Packit Service 084de1
    EVP_CIPHER_CTX_free(ctx);
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
void aes_ccm_decrypt(void)
Packit Service 084de1
{
Packit Service 084de1
    EVP_CIPHER_CTX *ctx;
Packit Service 084de1
    int outlen, tmplen, rv;
Packit Service 084de1
    unsigned char outbuf[1024];
Packit Service 084de1
    printf("AES CCM Derypt:\n");
Packit Service 084de1
    printf("Ciphertext:\n");
Packit Service 084de1
    BIO_dump_fp(stdout, ccm_ct, sizeof(ccm_ct));
Packit Service 084de1
    ctx = EVP_CIPHER_CTX_new();
Packit Service 084de1
    /* Select cipher */
Packit Service 084de1
    EVP_DecryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL);
Packit Service 084de1
    /* Set nonce length, omit for 96 bits */
Packit Service 084de1
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(ccm_nonce),
Packit Service 084de1
                        NULL);
Packit Service 084de1
    /* Set expected tag value */
Packit Service 084de1
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
Packit Service 084de1
                        sizeof(ccm_tag), (void *)ccm_tag);
Packit Service 084de1
    /* Specify key and IV */
Packit Service 084de1
    EVP_DecryptInit_ex(ctx, NULL, NULL, ccm_key, ccm_nonce);
Packit Service 084de1
    /* Set ciphertext length: only needed if we have AAD */
Packit Service 084de1
    EVP_DecryptUpdate(ctx, NULL, &outlen, NULL, sizeof(ccm_ct));
Packit Service 084de1
    /* Zero or one call to specify any AAD */
Packit Service 084de1
    EVP_DecryptUpdate(ctx, NULL, &outlen, ccm_adata, sizeof(ccm_adata));
Packit Service 084de1
    /* Decrypt plaintext, verify tag: can only be called once */
Packit Service 084de1
    rv = EVP_DecryptUpdate(ctx, outbuf, &outlen, ccm_ct, sizeof(ccm_ct));
Packit Service 084de1
    /* Output decrypted block: if tag verify failed we get nothing */
Packit Service 084de1
    if (rv > 0) {
Packit Service 084de1
        printf("Plaintext:\n");
Packit Service 084de1
        BIO_dump_fp(stdout, outbuf, outlen);
Packit Service 084de1
    } else
Packit Service 084de1
        printf("Plaintext not available: tag verify failed.\n");
Packit Service 084de1
    EVP_CIPHER_CTX_free(ctx);
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
int main(int argc, char **argv)
Packit Service 084de1
{
Packit Service 084de1
    aes_ccm_encrypt();
Packit Service 084de1
    aes_ccm_decrypt();
Packit Service 084de1
}