Branch data Line data Source code
1 : :
2 : : #ifndef COMPACT_DISABLE_X25519
3 : : #include "compact_x25519.h"
4 : : #include "c25519/c25519.h"
5 : : #include "c25519/sha512.h"
6 : : #include "compact_wipe.h"
7 : :
8 : 0 : void compact_x25519_keygen(
9 : : uint8_t private_key[X25519_KEY_SIZE],
10 : : uint8_t public_key[X25519_KEY_SIZE],
11 : : uint8_t random_seed[X25519_KEY_SIZE]
12 : : ) {
13 : 0 : memcpy(private_key, random_seed, X25519_KEY_SIZE);
14 : 0 : compact_wipe(random_seed, X25519_KEY_SIZE);
15 : 0 : c25519_prepare(private_key);
16 : 0 : c25519_smult(public_key, c25519_base_x, private_key);
17 : 0 : }
18 : :
19 : 0 : void compact_x25519_shared(
20 : : uint8_t shared_secret[X25519_SHARED_SIZE],
21 : : const uint8_t my_private_key[X25519_KEY_SIZE],
22 : : const uint8_t their_public_key[X25519_KEY_SIZE]
23 : : ) {
24 : : // Ensure that supplied private key is clamped (fix issue #1).
25 : : // Calling `c25519_prepare` multiple times for the same private key
26 : : // is OK because it won't modify already clamped key.
27 : 0 : uint8_t clamped_private_key[X25519_KEY_SIZE];
28 : 0 : memcpy(clamped_private_key, my_private_key, X25519_KEY_SIZE);
29 : : c25519_prepare(clamped_private_key);
30 : 0 : c25519_smult(shared_secret, their_public_key, clamped_private_key);
31 : 0 : compact_wipe(clamped_private_key, X25519_KEY_SIZE);
32 : 0 : }
33 : :
34 : : #ifndef COMPACT_DISABLE_X25519_DERIVE
35 : : #if (X25519_KEY_SIZE + (2 * X25519_KEY_SIZE)) > SHA512_BLOCK_SIZE
36 : : #error "Unexpected key sizes"
37 : : #endif
38 : :
39 : 0 : static uint8_t* append(uint8_t *dst, const void * source, size_t length) {
40 : 0 : memcpy(dst, source, length);
41 : 0 : return dst + length;
42 : : }
43 : :
44 : 0 : void compact_x25519_derive_encryption_key(
45 : : uint8_t *encryption_key,
46 : : size_t key_size,
47 : : const uint8_t shared_secret[X25519_SHARED_SIZE],
48 : : const uint8_t public_key1[X25519_KEY_SIZE],
49 : : const uint8_t public_key2[X25519_KEY_SIZE]
50 : : ) {
51 : 0 : if (key_size > SHA512_HASH_SIZE) {
52 : : key_size = SHA512_HASH_SIZE;
53 : : }
54 : 0 : uint8_t key_data[X25519_SHARED_SIZE + 2 * X25519_KEY_SIZE];
55 : 0 : uint8_t *p = key_data;
56 : 0 : p = append(p, shared_secret, X25519_SHARED_SIZE);
57 : 0 : p = append(p, public_key1, X25519_KEY_SIZE);
58 : 0 : append(p, public_key2, X25519_KEY_SIZE);
59 : :
60 : 0 : struct sha512_state hasher;
61 : 0 : sha512_init(&hasher);
62 : 0 : sha512_final(&hasher, key_data, sizeof(key_data));
63 : 0 : sha512_get(&hasher, encryption_key, 0, key_size);
64 : :
65 : 0 : compact_wipe(key_data, X25519_SHARED_SIZE); // clear the session key at least
66 : 0 : }
67 : : #endif
68 : : #endif
|