]>
Commit | Line | Data |
---|---|---|
0f113f3e MC |
1 | /* |
2 | * Simple AES GCM test program, uses the same NIST data used for the FIPS | |
07a4ff79 DSH |
3 | * self test but uses the application level EVP APIs. |
4 | */ | |
5 | #include <stdio.h> | |
6 | #include <openssl/bio.h> | |
7 | #include <openssl/evp.h> | |
8 | ||
9 | /* AES-GCM test data from NIST public test vectors */ | |
10 | ||
11 | static const unsigned char gcm_key[] = { | |
0f113f3e MC |
12 | 0xee, 0xbc, 0x1f, 0x57, 0x48, 0x7f, 0x51, 0x92, 0x1c, 0x04, 0x65, 0x66, |
13 | 0x5f, 0x8a, 0xe6, 0xd1, 0x65, 0x8b, 0xb2, 0x6d, 0xe6, 0xf8, 0xa0, 0x69, | |
14 | 0xa3, 0x52, 0x02, 0x93, 0xa5, 0x72, 0x07, 0x8f | |
07a4ff79 DSH |
15 | }; |
16 | ||
17 | static const unsigned char gcm_iv[] = { | |
0f113f3e | 18 | 0x99, 0xaa, 0x3e, 0x68, 0xed, 0x81, 0x73, 0xa0, 0xee, 0xd0, 0x66, 0x84 |
07a4ff79 DSH |
19 | }; |
20 | ||
21 | static const unsigned char gcm_pt[] = { | |
0f113f3e MC |
22 | 0xf5, 0x6e, 0x87, 0x05, 0x5b, 0xc3, 0x2d, 0x0e, 0xeb, 0x31, 0xb2, 0xea, |
23 | 0xcc, 0x2b, 0xf2, 0xa5 | |
07a4ff79 DSH |
24 | }; |
25 | ||
26 | static const unsigned char gcm_aad[] = { | |
0f113f3e MC |
27 | 0x4d, 0x23, 0xc3, 0xce, 0xc3, 0x34, 0xb4, 0x9b, 0xdb, 0x37, 0x0c, 0x43, |
28 | 0x7f, 0xec, 0x78, 0xde | |
07a4ff79 DSH |
29 | }; |
30 | ||
31 | static const unsigned char gcm_ct[] = { | |
0f113f3e MC |
32 | 0xf7, 0x26, 0x44, 0x13, 0xa8, 0x4c, 0x0e, 0x7c, 0xd5, 0x36, 0x86, 0x7e, |
33 | 0xb9, 0xf2, 0x17, 0x36 | |
07a4ff79 DSH |
34 | }; |
35 | ||
36 | static const unsigned char gcm_tag[] = { | |
0f113f3e MC |
37 | 0x67, 0xba, 0x05, 0x10, 0x26, 0x2a, 0xe4, 0x87, 0xd7, 0x37, 0xee, 0x62, |
38 | 0x98, 0xf7, 0x7e, 0x0c | |
07a4ff79 DSH |
39 | }; |
40 | ||
41 | void aes_gcm_encrypt(void) | |
0f113f3e MC |
42 | { |
43 | EVP_CIPHER_CTX *ctx; | |
44 | int outlen, tmplen; | |
45 | unsigned char outbuf[1024]; | |
46 | printf("AES GCM Encrypt:\n"); | |
47 | printf("Plaintext:\n"); | |
48 | BIO_dump_fp(stdout, gcm_pt, sizeof(gcm_pt)); | |
49 | ctx = EVP_CIPHER_CTX_new(); | |
50 | /* Set cipher type and mode */ | |
51 | EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); | |
52 | /* Set IV length if default 96 bits is not appropriate */ | |
53 | EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(gcm_iv), NULL); | |
54 | /* Initialise key and IV */ | |
55 | EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv); | |
56 | /* Zero or more calls to specify any AAD */ | |
57 | EVP_EncryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad)); | |
58 | /* Encrypt plaintext */ | |
59 | EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt)); | |
60 | /* Output encrypted block */ | |
61 | printf("Ciphertext:\n"); | |
62 | BIO_dump_fp(stdout, outbuf, outlen); | |
63 | /* Finalise: note get no output for GCM */ | |
64 | EVP_EncryptFinal_ex(ctx, outbuf, &outlen); | |
65 | /* Get tag */ | |
66 | EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, outbuf); | |
67 | /* Output tag */ | |
68 | printf("Tag:\n"); | |
69 | BIO_dump_fp(stdout, outbuf, 16); | |
70 | EVP_CIPHER_CTX_free(ctx); | |
71 | } | |
07a4ff79 DSH |
72 | |
73 | void aes_gcm_decrypt(void) | |
0f113f3e MC |
74 | { |
75 | EVP_CIPHER_CTX *ctx; | |
76 | int outlen, tmplen, rv; | |
77 | unsigned char outbuf[1024]; | |
78 | printf("AES GCM Derypt:\n"); | |
79 | printf("Ciphertext:\n"); | |
80 | BIO_dump_fp(stdout, gcm_ct, sizeof(gcm_ct)); | |
81 | ctx = EVP_CIPHER_CTX_new(); | |
82 | /* Select cipher */ | |
83 | EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); | |
84 | /* Set IV length, omit for 96 bits */ | |
85 | EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(gcm_iv), NULL); | |
86 | /* Specify key and IV */ | |
87 | EVP_DecryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv); | |
07a4ff79 | 88 | #if 0 |
0f113f3e MC |
89 | /* |
90 | * Set expected tag value. A restriction in OpenSSL 1.0.1c and earlier | |
91 | * required the tag before any AAD or ciphertext | |
92 | */ | |
93 | EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof(gcm_tag), gcm_tag); | |
07a4ff79 | 94 | #endif |
0f113f3e MC |
95 | /* Zero or more calls to specify any AAD */ |
96 | EVP_DecryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad)); | |
97 | /* Decrypt plaintext */ | |
98 | EVP_DecryptUpdate(ctx, outbuf, &outlen, gcm_ct, sizeof(gcm_ct)); | |
99 | /* Output decrypted block */ | |
100 | printf("Plaintext:\n"); | |
101 | BIO_dump_fp(stdout, outbuf, outlen); | |
102 | /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ | |
103 | EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, sizeof(gcm_tag), gcm_tag); | |
104 | /* Finalise: note get no output for GCM */ | |
105 | rv = EVP_DecryptFinal_ex(ctx, outbuf, &outlen); | |
106 | /* | |
107 | * Print out return value. If this is not successful authentication | |
108 | * failed and plaintext is not trustworthy. | |
109 | */ | |
110 | printf("Tag Verify %s\n", rv > 0 ? "Successful!" : "Failed!"); | |
111 | EVP_CIPHER_CTX_free(ctx); | |
112 | } | |
07a4ff79 DSH |
113 | |
114 | int main(int argc, char **argv) | |
0f113f3e MC |
115 | { |
116 | aes_gcm_encrypt(); | |
117 | aes_gcm_decrypt(); | |
118 | } |