blob: cc4d0b5ee99abc397942f7525bb807411c4b8cee [file] [log] [blame]
Matt Caswell0f113f32015-01-22 03:40:55 +00001/*
Rich Salz9e200682016-05-18 09:16:36 -04002 * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10/*
Matt Caswell0f113f32015-01-22 03:40:55 +000011 * Simple AES CCM test program, uses the same NIST data used for the FIPS
Dr. Stephen Hensone942c152013-03-05 18:29:14 +000012 * self test but uses the application level EVP APIs.
13 */
14#include <stdio.h>
15#include <openssl/bio.h>
16#include <openssl/evp.h>
17
18/* AES-CCM test data from NIST public test vectors */
19
20static const unsigned char ccm_key[] = {
Matt Caswell0f113f32015-01-22 03:40:55 +000021 0xce, 0xb0, 0x09, 0xae, 0xa4, 0x45, 0x44, 0x51, 0xfe, 0xad, 0xf0, 0xe6,
22 0xb3, 0x6f, 0x45, 0x55, 0x5d, 0xd0, 0x47, 0x23, 0xba, 0xa4, 0x48, 0xe8
Dr. Stephen Hensone942c152013-03-05 18:29:14 +000023};
24
25static const unsigned char ccm_nonce[] = {
Matt Caswell0f113f32015-01-22 03:40:55 +000026 0x76, 0x40, 0x43, 0xc4, 0x94, 0x60, 0xb7
Dr. Stephen Hensone942c152013-03-05 18:29:14 +000027};
28
29static const unsigned char ccm_adata[] = {
Matt Caswell0f113f32015-01-22 03:40:55 +000030 0x6e, 0x80, 0xdd, 0x7f, 0x1b, 0xad, 0xf3, 0xa1, 0xc9, 0xab, 0x25, 0xc7,
31 0x5f, 0x10, 0xbd, 0xe7, 0x8c, 0x23, 0xfa, 0x0e, 0xb8, 0xf9, 0xaa, 0xa5,
32 0x3a, 0xde, 0xfb, 0xf4, 0xcb, 0xf7, 0x8f, 0xe4
Dr. Stephen Hensone942c152013-03-05 18:29:14 +000033};
34
35static const unsigned char ccm_pt[] = {
Matt Caswell0f113f32015-01-22 03:40:55 +000036 0xc8, 0xd2, 0x75, 0xf9, 0x19, 0xe1, 0x7d, 0x7f, 0xe6, 0x9c, 0x2a, 0x1f,
37 0x58, 0x93, 0x9d, 0xfe, 0x4d, 0x40, 0x37, 0x91, 0xb5, 0xdf, 0x13, 0x10
Dr. Stephen Hensone942c152013-03-05 18:29:14 +000038};
39
40static const unsigned char ccm_ct[] = {
Matt Caswell0f113f32015-01-22 03:40:55 +000041 0x8a, 0x0f, 0x3d, 0x82, 0x29, 0xe4, 0x8e, 0x74, 0x87, 0xfd, 0x95, 0xa2,
42 0x8a, 0xd3, 0x92, 0xc8, 0x0b, 0x36, 0x81, 0xd4, 0xfb, 0xc7, 0xbb, 0xfd
Dr. Stephen Hensone942c152013-03-05 18:29:14 +000043};
44
45static const unsigned char ccm_tag[] = {
Matt Caswell0f113f32015-01-22 03:40:55 +000046 0x2d, 0xd6, 0xef, 0x1c, 0x45, 0xd4, 0xcc, 0xb7, 0x23, 0xdc, 0x07, 0x44,
47 0x14, 0xdb, 0x50, 0x6d
Dr. Stephen Hensone942c152013-03-05 18:29:14 +000048};
49
50void aes_ccm_encrypt(void)
Matt Caswell0f113f32015-01-22 03:40:55 +000051{
52 EVP_CIPHER_CTX *ctx;
53 int outlen, tmplen;
54 unsigned char outbuf[1024];
55 printf("AES CCM Encrypt:\n");
56 printf("Plaintext:\n");
57 BIO_dump_fp(stdout, ccm_pt, sizeof(ccm_pt));
58 ctx = EVP_CIPHER_CTX_new();
59 /* Set cipher type and mode */
60 EVP_EncryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL);
61 /* Set nonce length if default 96 bits is not appropriate */
Matt Caswelle640fa02015-01-27 14:05:07 +000062 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(ccm_nonce),
63 NULL);
Matt Caswell0f113f32015-01-22 03:40:55 +000064 /* Set tag length */
Matt Caswelle640fa02015-01-27 14:05:07 +000065 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, sizeof(ccm_tag), NULL);
Matt Caswell0f113f32015-01-22 03:40:55 +000066 /* Initialise key and IV */
67 EVP_EncryptInit_ex(ctx, NULL, NULL, ccm_key, ccm_nonce);
68 /* Set plaintext length: only needed if AAD is used */
69 EVP_EncryptUpdate(ctx, NULL, &outlen, NULL, sizeof(ccm_pt));
70 /* Zero or one call to specify any AAD */
71 EVP_EncryptUpdate(ctx, NULL, &outlen, ccm_adata, sizeof(ccm_adata));
72 /* Encrypt plaintext: can only be called once */
73 EVP_EncryptUpdate(ctx, outbuf, &outlen, ccm_pt, sizeof(ccm_pt));
74 /* Output encrypted block */
75 printf("Ciphertext:\n");
76 BIO_dump_fp(stdout, outbuf, outlen);
77 /* Finalise: note get no output for CCM */
78 EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
79 /* Get tag */
Matt Caswelle640fa02015-01-27 14:05:07 +000080 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outbuf);
Matt Caswell0f113f32015-01-22 03:40:55 +000081 /* Output tag */
82 printf("Tag:\n");
83 BIO_dump_fp(stdout, outbuf, 16);
84 EVP_CIPHER_CTX_free(ctx);
85}
Dr. Stephen Hensone942c152013-03-05 18:29:14 +000086
87void aes_ccm_decrypt(void)
Matt Caswell0f113f32015-01-22 03:40:55 +000088{
89 EVP_CIPHER_CTX *ctx;
90 int outlen, tmplen, rv;
91 unsigned char outbuf[1024];
92 printf("AES CCM Derypt:\n");
93 printf("Ciphertext:\n");
94 BIO_dump_fp(stdout, ccm_ct, sizeof(ccm_ct));
95 ctx = EVP_CIPHER_CTX_new();
96 /* Select cipher */
97 EVP_DecryptInit_ex(ctx, EVP_aes_192_ccm(), NULL, NULL, NULL);
98 /* Set nonce length, omit for 96 bits */
Matt Caswelle640fa02015-01-27 14:05:07 +000099 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, sizeof(ccm_nonce),
100 NULL);
Matt Caswell0f113f32015-01-22 03:40:55 +0000101 /* Set expected tag value */
Matt Caswelle640fa02015-01-27 14:05:07 +0000102 EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG,
Matt Caswell0f113f32015-01-22 03:40:55 +0000103 sizeof(ccm_tag), (void *)ccm_tag);
104 /* Specify key and IV */
105 EVP_DecryptInit_ex(ctx, NULL, NULL, ccm_key, ccm_nonce);
106 /* Set ciphertext length: only needed if we have AAD */
107 EVP_DecryptUpdate(ctx, NULL, &outlen, NULL, sizeof(ccm_ct));
108 /* Zero or one call to specify any AAD */
109 EVP_DecryptUpdate(ctx, NULL, &outlen, ccm_adata, sizeof(ccm_adata));
110 /* Decrypt plaintext, verify tag: can only be called once */
111 rv = EVP_DecryptUpdate(ctx, outbuf, &outlen, ccm_ct, sizeof(ccm_ct));
112 /* Output decrypted block: if tag verify failed we get nothing */
113 if (rv > 0) {
114 printf("Plaintext:\n");
115 BIO_dump_fp(stdout, outbuf, outlen);
116 } else
117 printf("Plaintext not available: tag verify failed.\n");
118 EVP_CIPHER_CTX_free(ctx);
119}
Dr. Stephen Hensone942c152013-03-05 18:29:14 +0000120
121int main(int argc, char **argv)
Matt Caswell0f113f32015-01-22 03:40:55 +0000122{
123 aes_ccm_encrypt();
124 aes_ccm_decrypt();
125}