Ockam logo
Product
OverviewCloud SDKEdge SDKEmbedded SDKRegistryRouter
Contact us

AEAD AES 128 GCM

The AEAD operation used in this example is AEAD_AES_128_GCM, which is precisely defined in RFC 5116.

AEAD AES 128 GCM Encrypt

Using an ockam secret containing the AES128 key we can use the encrypt function to generate an encrypted ciphertext. The output of the encrypt function is the encrypted ciphertext + a 16 byte tag attached to the end of the ciphertext. This means when creating a buffer for the output of encrypt, the buffer must be 16 bytes longer than the plaintext that's being encrypted.

1uint16_t nonce = 1;
2
3char* additional_data = "some metadata that will be authenticated but not encrypted";
4size_t additional_data_length = strlen(additional_data);
5
6char* plaintext = "some data that will be encrypted";
7size_t plaintext_length = strlen(plaintext);
8
9size_t ciphertext_and_tag_size = plaintext_length + OCKAM_VAULT_AEAD_AES_GCM_TAG_LENGTH;
10uint8_t* ciphertext_and_tag;
11size_t ciphertext_and_tag_length;
12
13error = ockam_memory_alloc_zeroed(&memory, &ciphertext_and_tag, ciphertext_and_tag_size);
14if (error) goto exit;
15
16error = ockam_vault_aead_aes_gcm_encrypt(&vault,
17 &key,
18 nonce,
19 (uint8_t*) additional_data,
20 additional_data_length,
21 (uint8_t*) plaintext,
22 plaintext_length,
23 ciphertext_and_tag,
24 ciphertext_and_tag_size,
25 &ciphertext_and_tag_length);
26if (error) goto exit;

AEAD AES 128 GCM Decrypt

To decrypt the ciphertext and tag data, the device receiving the data would need to have arrived at the same AES128 key through a key agreement scheme first. Using the same AES128 key, along with the same nonce value and additional data, the ciphertext and tag data can be passed into decrypt. The result will be a buffer 16 bytes less than the ciphertext and tag, and will contain the decrypted message.

1uint16_t nonce = 1;
2
3char* additional_data = "some metadata that will be authenticated but not encrypted";
4size_t additional_data_length = strlen(additional_data);
5
6size_t decrypted_plaintext_size = plaintext_length;
7uint8_t* decrypted_plaintext;
8size_t decrypted_plaintext_length;
9
10error = ockam_memory_alloc_zeroed(&memory, &decrypted_plaintext, decrypted_plaintext_size);
11if (error) goto exit;
12
13error = ockam_vault_aead_aes_gcm_decrypt(&vault,
14 &key,
15 nonce,
16 (uint8_t*) additional_data,
17 additional_data_length,
18 ciphertext_and_tag,
19 ciphertext_and_tag_length,
20 decrypted_plaintext,
21 decrypted_plaintext_size,
22 &decrypted_plaintext_length);
23if (error) goto exit;

Complete Example

This example shows the following:

  • Generate 16 bytes of random data to use for an AES key.
  • Create an ockam vault secret using the 16 bytes of random data.
  • Encrypt a payload using the AES key, additional data and nonce.
  • Decrypt the ciphertext + tag using the AES key, additional data and nonce.
  • Print out the resuling ciphertext + tag and the decrypted data.
1
2#include "ockam/error.h"
3
4#include "ockam/memory.h"
5#include "ockam/memory/stdlib.h"
6
7#include "ockam/random.h"
8#include "ockam/random/urandom.h"
9
10#include "ockam/vault.h"
11#include "ockam/vault/default.h"
12
13#include <stdio.h>
14
15int main(void)
16{
17 int exit_code = 0;
18
19 ockam_error_t error = OCKAM_ERROR_NONE;
20 ockam_error_t deinit_error = OCKAM_ERROR_NONE;
21
22 ockam_memory_t memory = { 0 };
23 ockam_random_t random = { 0 };
24 ockam_vault_t vault = { 0 };
25 ockam_vault_default_attributes_t vault_attributes = { .memory = &memory, .random = &random };
26
27 error = ockam_memory_stdlib_init(&memory);
28 if (error != OCKAM_ERROR_NONE) { goto exit; }
29
30 error = ockam_random_urandom_init(&random);
31 if (error != OCKAM_ERROR_NONE) { goto exit; }
32
33 error = ockam_vault_default_init(&vault, &vault_attributes);
34 if (error != OCKAM_ERROR_NONE) { goto exit; }
35
36 /*
37 * Generate a 16 byte random number to use as the AES key
38 */
39
40 uint8_t buffer[16];
41
42 error = ockam_vault_random_bytes_generate(&vault, &buffer[0], 16);
43 if(error != OCKAM_ERROR_NONE) goto exit;
44
45 /*
46 * Import the 16 byte random data into a vault secret
47 */
48
49 ockam_vault_secret_t key = { 0 };
50 ockam_vault_secret_attributes_t key_attributes = { 0 };
51
52 key_attributes.length = 16;
53 key_attributes.type = OCKAM_VAULT_SECRET_TYPE_AES128_KEY;
54 key_attributes.purpose = OCKAM_VAULT_SECRET_PURPOSE_KEY_AGREEMENT;
55 key_attributes.persistence = OCKAM_VAULT_SECRET_EPHEMERAL;
56
57 error = ockam_vault_secret_import(&vault,
58 &key,
59 &key_attributes,
60 &buffer[0],
61 16);
62 if(error != OCKAM_ERROR_NONE) goto exit;
63
64
65 /* Encrypt the plaintext using the the key, additional data and nonce. */
66
67 uint16_t nonce = 1;
68
69 char* additional_data = "some metadata that will be authenticated but not encrypted";
70 size_t additional_data_length = strlen(additional_data);
71
72 char* plaintext = "some data that will be encrypted";
73 size_t plaintext_length = strlen(plaintext);
74
75 size_t ciphertext_and_tag_size = plaintext_length + OCKAM_VAULT_AEAD_AES_GCM_TAG_LENGTH;
76 uint8_t* ciphertext_and_tag;
77 size_t ciphertext_and_tag_length;
78
79 error = ockam_memory_alloc_zeroed(&memory, &ciphertext_and_tag, ciphertext_and_tag_size);
80 if (error) goto exit;
81
82 error = ockam_vault_aead_aes_gcm_encrypt(&vault,
83 &key,
84 nonce,
85 (uint8_t*) additional_data,
86 additional_data_length,
87 (uint8_t*) plaintext,
88 plaintext_length,
89 ciphertext_and_tag,
90 ciphertext_and_tag_size,
91 &ciphertext_and_tag_length);
92 if (error) goto exit;
93
94 printf("Encrypted ciphertext and tag : ");
95 for(int i = 0; i < ciphertext_and_tag_size; i++) {
96 printf("%02x", ciphertext_and_tag[i]);
97 }
98 printf("\r\n");
99
100 /*
101 * Decrypt the ciphertext + tag using the same key, additional data and nonce.
102 */
103
104 size_t decrypted_plaintext_size = plaintext_length;
105 uint8_t* decrypted_plaintext;
106 size_t decrypted_plaintext_length;
107
108 error = ockam_memory_alloc_zeroed(&memory, &decrypted_plaintext, decrypted_plaintext_size);
109 if (error) goto exit;
110
111 error = ockam_vault_aead_aes_gcm_decrypt(&vault,
112 &key,
113 nonce,
114 (uint8_t*) additional_data,
115 additional_data_length,
116 ciphertext_and_tag,
117 ciphertext_and_tag_length,
118 decrypted_plaintext,
119 decrypted_plaintext_size,
120 &decrypted_plaintext_length);
121 if (error) goto exit;
122
123
124 printf("Decrypted plaintext : ");
125 printf("%s\r\n", decrypted_plaintext);
126
127exit:
128
129 ockam_memory_free(&memory, ciphertext_and_tag, ciphertext_and_tag_size);
130 ockam_memory_free(&memory, decrypted_plaintext, decrypted_plaintext_size);
131 ockam_vault_secret_destroy(&vault, &key);
132
133 deinit_error = ockam_vault_deinit(&vault);
134 ockam_random_deinit(&random);
135 ockam_memory_deinit(&memory);
136
137 if (error == OCKAM_ERROR_NONE) { error = deinit_error; }
138 if (error != OCKAM_ERROR_NONE) { exit_code = -1; }
139 return exit_code;
140}
Previous

HKDF-SHA256

On this page
Edit this page
Star Ockam repo