Ockam logo
Product
OverviewCloud SDKEdge SDKEmbedded SDKRegistryRouter
Contact us

HKDF-SHA256

The HKDF operation used in this example is HKDF-SHA256, which is defined in RFC 5869.

Import salt and input key material

The HKDF-SHA256 operation requires a salt secret, and while not required, typically also takes in an input key material secret. Since HKDF-SHA256 needs this data as secrets, the data must be loaded into a secret before the HKDF-SHA256 operation can be called. The example code below shows loading salt and input key material data into two secret types.

1#define EXAMPLE_VAULT_HKDF_IKM_LENGTH 32u
2#define EXAMPLE_VAULT_HKDF_SALT_LENGTH 28u
3
4uint8_t g_hkdf_ikm[] =
5{
6 0x37, 0xe0, 0xe7, 0xda, 0xac, 0xbd, 0x6b, 0xfb,
7 0xf6, 0x69, 0xa8, 0x46, 0x19, 0x6f, 0xd4, 0x4d,
8 0x1c, 0x87, 0x45, 0xd3, 0x3f, 0x2b, 0xe4, 0x2e,
9 0x31, 0xd4, 0x67, 0x41, 0x99, 0xad, 0x00, 0x5e
10};
11
12uint8_t g_hkdf_salt[] =
13{
14 0x4e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x58, 0x58,
15 0x5f, 0x32, 0x35, 0x35, 0x31, 0x39, 0x5f, 0x41,
16 0x45, 0x53, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48,
17 0x41, 0x32, 0x35, 0x36
18};
19
20ockam_vault_secret_t salt = { 0 };
21ockam_vault_secret_t input_key_material = { 0 };
22ockam_vault_secret_attributes_t attributes = { 0 };
23
24attributes.type = OCKAM_VAULT_SECRET_TYPE_BUFFER;
25attributes.purpose = OCKAM_VAULT_SECRET_PURPOSE_KEY_AGREEMENT;
26attributes.persistence = OCKAM_VAULT_SECRET_EPHEMERAL;
27
28attributes.length = EXAMPLE_VAULT_HKDF_IKM_LENGTH;
29error = ockam_vault_secret_import(&vault,
30 &input_key_material,
31 &attributes,
32 &g_hkdf_ikm[0],
33 EXAMPLE_VAULT_HKDF_IKM_LENGTH);
34if (error != OCKAM_ERROR_NONE) { goto exit; }
35
36attributes.length = EXAMPLE_VAULT_HKDF_SALT_LENGTH;
37error = ockam_vault_secret_import(&vault,
38 &salt,
39 &attributes,
40 &g_hkdf_salt[0],
41 EXAMPLE_VAULT_HKDF_SALT_LENGTH);
42if (error != OCKAM_ERROR_NONE) { goto exit; }

HKDF-SHA256

Once the salt and input key material secrets are loaded, the HKDF-SHA256 function can be called. The output of the function is an array of 32-byte derived outputs stored in secret types. The number of derived outputs depends on the number specified in the HKDF-SHA256 call. Typically the number of derived outputs will be 2 or 3.

1ockam_vault_secret_t derived_outputs[2];
2
3error = ockam_vault_hkdf_sha256(&vault,
4 &salt,
5 &input_key_material,
6 2,
7 &derived_outputs[0]);
8if (error != OCKAM_ERROR_NONE) { goto exit; }

Complete Example

The sample below shows the following:

  • Import salt and input key material into secrets
  • Run the HKDF-SHA256 to generate 2 derived outputs
  • Retrieve the derived outputs and print out the results
1#include "ockam/error.h"
2
3#include "ockam/memory.h"
4#include "ockam/memory/stdlib.h"
5
6#include "ockam/random.h"
7#include "ockam/random/urandom.h"
8
9#include "ockam/vault.h"
10#include "ockam/vault/default.h"
11
12#include <stdio.h>
13#include <string.h>
14
15
16#define EXAMPLE_VAULT_HKDF_IKM_LENGTH 32u
17#define EXAMPLE_VAULT_HKDF_SALT_LENGTH 28u
18
19uint8_t g_hkdf_ikm[] =
20{
21 0x37, 0xe0, 0xe7, 0xda, 0xac, 0xbd, 0x6b, 0xfb,
22 0xf6, 0x69, 0xa8, 0x46, 0x19, 0x6f, 0xd4, 0x4d,
23 0x1c, 0x87, 0x45, 0xd3, 0x3f, 0x2b, 0xe4, 0x2e,
24 0x31, 0xd4, 0x67, 0x41, 0x99, 0xad, 0x00, 0x5e
25};
26
27uint8_t g_hkdf_salt[] =
28{
29 0x4e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x58, 0x58,
30 0x5f, 0x32, 0x35, 0x35, 0x31, 0x39, 0x5f, 0x41,
31 0x45, 0x53, 0x47, 0x43, 0x4d, 0x5f, 0x53, 0x48,
32 0x41, 0x32, 0x35, 0x36
33};
34
35int main(void)
36{
37 int exit_code = 0;
38
39 ockam_error_t error = OCKAM_ERROR_NONE;
40 ockam_error_t deinit_error = OCKAM_ERROR_NONE;
41
42 ockam_memory_t memory = { 0 };
43 ockam_random_t random = { 0 };
44 ockam_vault_t vault = { 0 };
45 ockam_vault_default_attributes_t vault_attributes = { .memory = &memory, .random = &random };
46
47 error = ockam_memory_stdlib_init(&memory);
48 if (error != OCKAM_ERROR_NONE) { goto exit; }
49
50 error = ockam_random_urandom_init(&random);
51 if (error != OCKAM_ERROR_NONE) { goto exit; }
52
53 error = ockam_vault_default_init(&vault, &vault_attributes);
54 if (error != OCKAM_ERROR_NONE) { goto exit; }
55
56 /* Import the salt and input key material into ockam vault secrets */
57
58 ockam_vault_secret_t salt = { 0 };
59 ockam_vault_secret_t input_key_material = { 0 };
60 ockam_vault_secret_attributes_t attributes = { 0 };
61
62 attributes.type = OCKAM_VAULT_SECRET_TYPE_BUFFER;
63 attributes.purpose = OCKAM_VAULT_SECRET_PURPOSE_KEY_AGREEMENT;
64 attributes.persistence = OCKAM_VAULT_SECRET_EPHEMERAL;
65
66 attributes.length = EXAMPLE_VAULT_HKDF_IKM_LENGTH;
67 error = ockam_vault_secret_import(&vault,
68 &input_key_material,
69 &attributes,
70 &g_hkdf_ikm[0],
71 EXAMPLE_VAULT_HKDF_IKM_LENGTH);
72 if (error != OCKAM_ERROR_NONE) { goto exit; }
73
74 attributes.length = EXAMPLE_VAULT_HKDF_SALT_LENGTH;
75 error = ockam_vault_secret_import(&vault,
76 &salt,
77 &attributes,
78 &g_hkdf_salt[0],
79 EXAMPLE_VAULT_HKDF_SALT_LENGTH);
80 if (error != OCKAM_ERROR_NONE) { goto exit; }
81
82
83 /* Calculate two derived outputs from the salt and input key material */
84
85 ockam_vault_secret_t derived_outputs[2];
86
87 error = ockam_vault_hkdf_sha256(&vault,
88 &salt,
89 &input_key_material,
90 2,
91 &derived_outputs[0]);
92 if (error != OCKAM_ERROR_NONE) { goto exit; }
93
94 /* Retrieve the two derived outputs and print them out */
95
96 size_t derived_output_length = 0;
97 uint8_t derived_output_data_0[OCKAM_VAULT_SHA256_DIGEST_LENGTH] = { 0 };
98 uint8_t derived_output_data_1[OCKAM_VAULT_SHA256_DIGEST_LENGTH] = { 0 };
99
100 error = ockam_vault_secret_export(&vault,
101 &derived_outputs[0],
102 &derived_output_data_0[0],
103 OCKAM_VAULT_SHA256_DIGEST_LENGTH,
104 &derived_output_length);
105 if (error != OCKAM_ERROR_NONE) { goto exit; }
106 if (derived_output_length != OCKAM_VAULT_SHA256_DIGEST_LENGTH) { goto exit; }
107
108 error = ockam_vault_secret_export(&vault,
109 &derived_outputs[1],
110 &derived_output_data_1[0],
111 OCKAM_VAULT_SHA256_DIGEST_LENGTH,
112 &derived_output_length);
113 if (error != OCKAM_ERROR_NONE) { goto exit; }
114 if (derived_output_length != OCKAM_VAULT_SHA256_DIGEST_LENGTH) { goto exit; }
115
116
117 int i;
118 printf("Derived Output 0: ");
119 for (i = 0; i < OCKAM_VAULT_SHA256_DIGEST_LENGTH; i++) { printf("%02x", derived_output_data_0[i]); }
120 printf("\n");
121
122 printf("Derived Output 1: ");
123 for (i = 0; i < OCKAM_VAULT_SHA256_DIGEST_LENGTH; i++) { printf("%02x", derived_output_data_1[i]); }
124 printf("\n");
125
126exit:
127
128 /* Clean up all secrets used in the example */
129
130 ockam_vault_secret_destroy(&vault, &salt);
131 ockam_vault_secret_destroy(&vault, &input_key_material);
132 ockam_vault_secret_destroy(&vault, &derived_outputs[0]);
133 ockam_vault_secret_destroy(&vault, &derived_outputs[1]);
134
135 /* Deinitialize to free resources associated with this handle. */
136
137 deinit_error = ockam_vault_deinit(&vault);
138 ockam_random_deinit(&random);
139 ockam_memory_deinit(&memory);
140
141 if (error == OCKAM_ERROR_NONE) { error = deinit_error; }
142 if (error != OCKAM_ERROR_NONE) { exit_code = -1; }
143 return exit_code;
144}
145
146
147
148export const _frontmatter = {"order":5,"title":"HKDF-SHA256"}
Previous

Key Generation/ECDH

Next

AEAD AES 128 GCM

On this page
Edit this page
Star Ockam repo