1
2 #include <stddef.h>
3
4 #include "core.h"
5 #include "crypto_generichash.h"
6 #include "crypto_kx.h"
7 #include "crypto_scalarmult.h"
8 #include "private/common.h"
9 #include "randombytes.h"
10 #include "utils.h"
11
12 int
crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],unsigned char sk[crypto_kx_SECRETKEYBYTES],const unsigned char seed[crypto_kx_SEEDBYTES])13 crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
14 unsigned char sk[crypto_kx_SECRETKEYBYTES],
15 const unsigned char seed[crypto_kx_SEEDBYTES])
16 {
17 crypto_generichash(sk, crypto_kx_SECRETKEYBYTES,
18 seed, crypto_kx_SEEDBYTES, NULL, 0);
19 return crypto_scalarmult_base(pk, sk);
20 }
21
22 int
crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],unsigned char sk[crypto_kx_SECRETKEYBYTES])23 crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
24 unsigned char sk[crypto_kx_SECRETKEYBYTES])
25 {
26 COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES);
27 COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES);
28
29 randombytes_buf(sk, crypto_kx_SECRETKEYBYTES);
30 return crypto_scalarmult_base(pk, sk);
31 }
32
33 int
crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],unsigned char tx[crypto_kx_SESSIONKEYBYTES],const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])34 crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
35 unsigned char tx[crypto_kx_SESSIONKEYBYTES],
36 const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES],
37 const unsigned char client_sk[crypto_kx_SECRETKEYBYTES],
38 const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES])
39 {
40 crypto_generichash_state h;
41 unsigned char q[crypto_scalarmult_BYTES];
42 unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES];
43 int i;
44
45 if (rx == NULL) {
46 rx = tx;
47 }
48 if (tx == NULL) {
49 tx = rx;
50 }
51 if (rx == NULL) {
52 sodium_misuse(); /* LCOV_EXCL_LINE */
53 }
54 if (crypto_scalarmult(q, client_sk, server_pk) != 0) {
55 return -1;
56 }
57 COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
58 crypto_generichash_init(&h, NULL, 0U, sizeof keys);
59 crypto_generichash_update(&h, q, crypto_scalarmult_BYTES);
60 sodium_memzero(q, sizeof q);
61 crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
62 crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
63 crypto_generichash_final(&h, keys, sizeof keys);
64 sodium_memzero(&h, sizeof h);
65 for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
66 rx[i] = keys[i];
67 tx[i] = keys[i + crypto_kx_SESSIONKEYBYTES];
68 }
69 sodium_memzero(keys, sizeof keys);
70
71 return 0;
72 }
73
74 int
crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],unsigned char tx[crypto_kx_SESSIONKEYBYTES],const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES],const unsigned char server_sk[crypto_kx_SECRETKEYBYTES],const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES])75 crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES],
76 unsigned char tx[crypto_kx_SESSIONKEYBYTES],
77 const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES],
78 const unsigned char server_sk[crypto_kx_SECRETKEYBYTES],
79 const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES])
80 {
81 crypto_generichash_state h;
82 unsigned char q[crypto_scalarmult_BYTES];
83 unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES];
84 int i;
85
86 if (rx == NULL) {
87 rx = tx;
88 }
89 if (tx == NULL) {
90 tx = rx;
91 }
92 if (rx == NULL) {
93 sodium_misuse(); /* LCOV_EXCL_LINE */
94 }
95 if (crypto_scalarmult(q, server_sk, client_pk) != 0) {
96 return -1;
97 }
98 COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX);
99 crypto_generichash_init(&h, NULL, 0U, sizeof keys);
100 crypto_generichash_update(&h, q, crypto_scalarmult_BYTES);
101 sodium_memzero(q, sizeof q);
102 crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES);
103 crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES);
104 crypto_generichash_final(&h, keys, sizeof keys);
105 sodium_memzero(&h, sizeof h);
106 for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) {
107 tx[i] = keys[i];
108 rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES];
109 }
110 sodium_memzero(keys, sizeof keys);
111
112 return 0;
113 }
114
115 size_t
crypto_kx_publickeybytes(void)116 crypto_kx_publickeybytes(void)
117 {
118 return crypto_kx_PUBLICKEYBYTES;
119 }
120
121 size_t
crypto_kx_secretkeybytes(void)122 crypto_kx_secretkeybytes(void)
123 {
124 return crypto_kx_SECRETKEYBYTES;
125 }
126
127 size_t
crypto_kx_seedbytes(void)128 crypto_kx_seedbytes(void)
129 {
130 return crypto_kx_SEEDBYTES;
131 }
132
133 size_t
crypto_kx_sessionkeybytes(void)134 crypto_kx_sessionkeybytes(void)
135 {
136 return crypto_kx_SESSIONKEYBYTES;
137 }
138
139 const char *
crypto_kx_primitive(void)140 crypto_kx_primitive(void)
141 {
142 return crypto_kx_PRIMITIVE;
143 }
144