Ockam logo
Product
OverviewCloud SDKEdge SDKEmbedded SDKRegistryRouter
Contact us

Key Generation/ECDH

The ECDH operation requires the use of ockam_vault_secret_t to contain a private key. Additionally the output of the ECDH operation will be another ockam_vault_secret_t. This guide will walk through creating 2 private key secrets, retrieving the public keys for each secret, performing ECDH on each private key with the other's public key and retrieving the matching shared secrets from the two ECDH operations.

Secret Generate

To generate a private key on Curve25519, ockam_vault_secret_t and ockam_vault_secret_attributes_t structs must be declared. The attributes field must be populated as shown below. The length field can be set to zero as the size of a Curve25519 is fixed as part of Ockam Vault.

1 ockam_vault_secret_t secret = { 0 };
2 ockam_vault_secret_attributes_t attributes = { 0 };
3
4 attributes.length = 0;
5 attributes.type = OCKAM_VAULT_SECRET_TYPE_CURVE25519_PRIVATEKEY;
6 attributes.purpose = OCKAM_VAULT_SECRET_PURPOSE_KEY_AGREEMENT;
7 attributes.persistence = OCKAM_VAULT_SECRET_EPHEMERAL;
8
9 error = ockam_vault_secret_generate(&vault, &secret, &attributes);
10 if (error != OCKAM_ERROR_NONE) { goto exit; }

The result of the ockam_vault_secret_generate function is a newly generated private key stored in Vault.

Public Key Retrieval

Once a private key has been generated, the public key can be retrieved from the private key and stored into a buffer passed into the function ockam_vault_secret_publickey_get. The size of the Curve25519 public key is provided in vault.h as a define. The public key buffer must be at least the size of the define, but it is valid to be larger than the defined length. The amount of data actually placed in the buffer is set in the length field.

1size_t public_key_length = 0;
2uint8_t public_key[OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH] = { 0 };
3
4error = ockam_vault_secret_publickey_get(&vault,
5 &secret,
6 &public_key[0],
7 OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH,
8 &public_key_length);
9 if (error != OCKAM_ERROR_NONE) { goto exit; }
10 if (public_key_length != OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH) { goto exit; }

ECDH

To calculate the shared secret using ECDH, a private key in a vault secret and a public key is needed. The sample below assumes the device executing the ECDH operation has received a public key from a device its attempting to communicate with. The the private key secret is passed in along with the public key and the result is a new vault secret containing the calculated shared secret. The secret type will be set to OCKAM_VAULT_SECRET_TYPE_BUFFER.

1ockam_vault_secret_t shared_secret = { 0 };
2
3error = ockam_vault_ecdh(&vault,
4 &secret,
5 &external_public_key[0],
6 OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH,
7 &shared_secret);
8if (error != OCKAM_ERROR_NONE) { goto exit; }

Complete Example

The sample below shows the following:

  • Generate two private keys.
  • Retrive the two public keys.
  • Calculate the shared secrets.
  • Retrieve the shared secrets and print out to show they match.
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 t_error = OCKAM_ERROR_NONE;
21
22 /* Initialize the default vault using urandom for random and stdlib for memory */
23
24 ockam_memory_t memory = { 0 };
25 ockam_random_t random = { 0 };
26 ockam_vault_t vault = { 0 };
27 ockam_vault_default_attributes_t vault_attributes = { .memory = &memory, .random = &random };
28
29 error = ockam_memory_stdlib_init(&memory);
30 if (error != OCKAM_ERROR_NONE) { goto exit; }
31
32 error = ockam_random_urandom_init(&random);
33 if (error != OCKAM_ERROR_NONE) { goto exit; }
34
35 error = ockam_vault_default_init(&vault, &vault_attributes);
36 if (error != OCKAM_ERROR_NONE) { goto exit; }
37
38 /* Generate private key secrets for the initiator and responder */
39
40 ockam_vault_secret_t initiator_secret = { 0 };
41 ockam_vault_secret_t responder_secret = { 0 };
42 ockam_vault_secret_attributes_t attributes = { 0 };
43
44 attributes.length = 0;
45 attributes.type = OCKAM_VAULT_SECRET_TYPE_CURVE25519_PRIVATEKEY;
46 attributes.purpose = OCKAM_VAULT_SECRET_PURPOSE_KEY_AGREEMENT;
47 attributes.persistence = OCKAM_VAULT_SECRET_EPHEMERAL;
48
49 error = ockam_vault_secret_generate(&vault, &initiator_secret, &attributes);
50 if (error != OCKAM_ERROR_NONE) { goto exit; }
51
52 error = ockam_vault_secret_generate(&vault, &responder_secret, &attributes);
53 if (error != OCKAM_ERROR_NONE) { goto exit; }
54
55 /* Retrieve the public keys for both initiator and responder */
56
57 size_t public_key_length = 0;
58
59 uint8_t initiator_public_key[OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH] = { 0 };
60 uint8_t responder_public_key[OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH] = { 0 };
61
62 error = ockam_vault_secret_publickey_get(&vault,
63 &initiator_secret,
64 &initiator_public_key[0],
65 OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH,
66 &public_key_length);
67 if (error != OCKAM_ERROR_NONE) { goto exit; }
68 if (public_key_length != OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH) { goto exit; }
69
70 error = ockam_vault_secret_publickey_get(&vault,
71 &responder_secret,
72 &responder_public_key[0],
73 OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH,
74 &public_key_length);
75 if (error != OCKAM_ERROR_NONE) { goto exit; }
76 if (public_key_length != OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH) { goto exit; }
77
78 /*
79 * Calculate two shared secrets: initiator private/responder public and responder
80 * private/initiator public.
81 */
82
83 ockam_vault_secret_t shared_secret_0 = { 0 };
84 ockam_vault_secret_t shared_secret_1 = { 0 };
85
86 error = ockam_vault_ecdh(&vault,
87 &initiator_secret,
88 &responder_public_key[0],
89 OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH,
90 &shared_secret_0);
91 if (error != OCKAM_ERROR_NONE) { goto exit; }
92
93 error = ockam_vault_ecdh(&vault,
94 &responder_secret,
95 &initiator_public_key[0],
96 OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH,
97 &shared_secret_1);
98 if (error != OCKAM_ERROR_NONE) { goto exit; }
99
100 /* Retrieve the two calculated shared secrets and print them out */
101
102 size_t shared_secret_length = 0;
103
104 uint8_t shared_secret_0_data[OCKAM_VAULT_SHARED_SECRET_LENGTH] = { 0 };
105 uint8_t shared_secret_1_data[OCKAM_VAULT_SHARED_SECRET_LENGTH] = { 0 };
106
107 error = ockam_vault_secret_export(&vault,
108 &shared_secret_0,
109 &shared_secret_0_data[0],
110 OCKAM_VAULT_SHARED_SECRET_LENGTH,
111 &shared_secret_length);
112 if (error != OCKAM_ERROR_NONE) { goto exit; }
113 if (shared_secret_length != OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH) { goto exit; }
114
115 error = ockam_vault_secret_export(&vault,
116 &shared_secret_1,
117 &shared_secret_1_data[0],
118 OCKAM_VAULT_SHARED_SECRET_LENGTH,
119 &shared_secret_length);
120 if (error != OCKAM_ERROR_NONE) { goto exit; }
121 if (shared_secret_length != OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH) { goto exit; }
122
123 int i;
124 printf("Shared Secret 0: ");
125 for (i = 0; i < OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH; i++) { printf("%02x", shared_secret_0_data[i]); }
126 printf("\n");
127
128 printf("Shared Secret 1: ");
129 for (i = 0; i < OCKAM_VAULT_CURVE25519_PUBLICKEY_LENGTH; i++) { printf("%02x", shared_secret_1_data[i]); }
130 printf("\n");
131
132exit:
133
134 /* Destroy the secrets to free the associated resources */
135
136 ockam_vault_secret_destroy(&vault, &initiator_secret);
137 ockam_vault_secret_destroy(&vault, &responder_secret);
138 ockam_vault_secret_destroy(&vault, &shared_secret_0);
139 ockam_vault_secret_destroy(&vault, &shared_secret_1);
140
141 /* Deinitialize to free resources associated with this handle. */
142
143 t_error = ockam_vault_deinit(&vault);
144 ockam_random_deinit(&random);
145 ockam_memory_deinit(&memory);
146
147 if (error == OCKAM_ERROR_NONE) { error = t_error; }
148 if (error != OCKAM_ERROR_NONE) { exit_code = -1; }
149 return exit_code;
150}
Previous

SHA-256

Next

HKDF-SHA256

On this page
Edit this page
Star Ockam repo