summaryrefslogtreecommitdiff
path: root/linux-x86_64/include/openssl/curve25519.h
blob: 1bbb69a95a1880093d6d29efdab82280e5511829 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/* Copyright (c) 2015, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#ifndef OPENSSL_HEADER_CURVE25519_H
#define OPENSSL_HEADER_CURVE25519_H

#include <openssl/base.h>

#if defined(__cplusplus)
extern "C" {
#endif


/* Curve25519.
 *
 * Curve25519 is an elliptic curve. See https://tools.ietf.org/html/rfc7748. */


/* X25519.
 *
 * X25519 is the Diffie-Hellman primitive built from curve25519. It is
 * sometimes referred to as “curve25519”, but “X25519” is a more precise name.
 * See http://cr.yp.to/ecdh.html and https://tools.ietf.org/html/rfc7748. */

#define X25519_PRIVATE_KEY_LEN 32
#define X25519_PUBLIC_VALUE_LEN 32
#define X25519_SHARED_KEY_LEN 32

/* X25519_keypair sets |out_public_value| and |out_private_key| to a freshly
 * generated, public–private key pair. */
OPENSSL_EXPORT void X25519_keypair(uint8_t out_public_value[32],
                                   uint8_t out_private_key[32]);

/* X25519 writes a shared key to |out_shared_key| that is calculated from the
 * given private key and the peer's public value. It returns one on success and
 * zero on error.
 *
 * Don't use the shared key directly, rather use a KDF and also include the two
 * public values as inputs. */
OPENSSL_EXPORT int X25519(uint8_t out_shared_key[32],
                          const uint8_t private_key[32],
                          const uint8_t peers_public_value[32]);

/* X25519_public_from_private calculates a Diffie-Hellman public value from the
 * given private key and writes it to |out_public_value|. */
OPENSSL_EXPORT void X25519_public_from_private(uint8_t out_public_value[32],
                                               const uint8_t private_key[32]);


/* Ed25519.
 *
 * Ed25519 is a signature scheme using a twisted-Edwards curve that is
 * birationally equivalent to curve25519. */

#define ED25519_PRIVATE_KEY_LEN 64
#define ED25519_PUBLIC_KEY_LEN 32
#define ED25519_SIGNATURE_LEN 64

/* ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly
 * generated, public–private key pair. */
OPENSSL_EXPORT void ED25519_keypair(uint8_t out_public_key[32],
                                    uint8_t out_private_key[64]);

/* ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from
 * |message| using |private_key|. It returns one on success or zero on
 * error. */
OPENSSL_EXPORT int ED25519_sign(uint8_t out_sig[64], const uint8_t *message,
                                size_t message_len,
                                const uint8_t private_key[64]);

/* ED25519_verify returns one iff |signature| is a valid signature, by
 * |public_key| of |message_len| bytes from |message|. It returns zero
 * otherwise. */
OPENSSL_EXPORT int ED25519_verify(const uint8_t *message, size_t message_len,
                                  const uint8_t signature[64],
                                  const uint8_t public_key[32]);

/* ED25519_keypair_from_seed calculates a public and private key from an
 * Ed25519 “seed”. Seed values are not exposed by this API (although they
 * happen to be the first 32 bytes of a private key) so this function is for
 * interoperating with systems that may store just a seed instead of a full
 * private key. */
OPENSSL_EXPORT void ED25519_keypair_from_seed(uint8_t out_public_key[32],
                                              uint8_t out_private_key[64],
                                              const uint8_t seed[32]);


/* SPAKE2.
 *
 * SPAKE2 is a password-authenticated key-exchange. It allows two parties,
 * who share a low-entropy secret (i.e. password), to agree on a shared key.
 * An attacker can only make one guess of the password per execution of the
 * protocol.
 *
 * See https://tools.ietf.org/html/draft-irtf-cfrg-spake2-02. */

/* spake2_role_t enumerates the different “roles” in SPAKE2. The protocol
 * requires that the symmetry of the two parties be broken so one participant
 * must be “Alice” and the other be “Bob”. */
enum spake2_role_t {
  spake2_role_alice,
  spake2_role_bob,
};

/* SPAKE2_CTX_new creates a new |SPAKE2_CTX| (which can only be used for a
 * single execution of the protocol). SPAKE2 requires the symmetry of the two
 * parties to be broken which is indicated via |my_role| – each party must pass
 * a different value for this argument.
 *
 * The |my_name| and |their_name| arguments allow optional, opaque names to be
 * bound into the protocol. For example MAC addresses, hostnames, usernames
 * etc. These values are not exposed and can avoid context-confusion attacks
 * when a password is shared between several devices. */
OPENSSL_EXPORT SPAKE2_CTX *SPAKE2_CTX_new(
    enum spake2_role_t my_role,
    const uint8_t *my_name, size_t my_name_len,
    const uint8_t *their_name, size_t their_name_len);

/* SPAKE2_CTX_free frees |ctx| and all the resources that it has allocated. */
OPENSSL_EXPORT void SPAKE2_CTX_free(SPAKE2_CTX *ctx);

/* SPAKE2_MAX_MSG_SIZE is the maximum size of a SPAKE2 message. */
#define SPAKE2_MAX_MSG_SIZE 32

/* SPAKE2_generate_msg generates a SPAKE2 message given |password|, writes
 * it to |out| and sets |*out_len| to the number of bytes written.
 *
 * At most |max_out_len| bytes are written to |out| and, in order to ensure
 * success, |max_out_len| should be at least |SPAKE2_MAX_MSG_SIZE| bytes.
 *
 * This function can only be called once for a given |SPAKE2_CTX|.
 *
 * It returns one on success and zero on error. */
OPENSSL_EXPORT int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out,
                                       size_t *out_len, size_t max_out_len,
                                       const uint8_t *password,
                                       size_t password_len);

/* SPAKE2_MAX_KEY_SIZE is the maximum amount of key material that SPAKE2 will
 * produce. */
#define SPAKE2_MAX_KEY_SIZE 64

/* SPAKE2_process_msg completes the SPAKE2 exchange given the peer's message in
 * |their_msg|, writes at most |max_out_key_len| bytes to |out_key| and sets
 * |*out_key_len| to the number of bytes written.
 *
 * The resulting keying material is suitable for:
 *   a) Using directly in a key-confirmation step: i.e. each side could
 *      transmit a hash of their role, a channel-binding value and the key
 *      material to prove to the other side that they know the shared key.
 *   b) Using as input keying material to HKDF to generate a variety of subkeys
 *      for encryption etc.
 *
 * If |max_out_key_key| is smaller than the amount of key material generated
 * then the key is silently truncated. If you want to ensure that no truncation
 * occurs then |max_out_key| should be at least |SPAKE2_MAX_KEY_SIZE|.
 *
 * You must call |SPAKE2_generate_msg| on a given |SPAKE2_CTX| before calling
 * this function. On successful return, |ctx| is complete and calling
 * |SPAKE2_CTX_free| is the only acceptable operation on it.
 *
 * Returns one on success or zero on error. */
OPENSSL_EXPORT int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key,
                                      size_t *out_key_len,
                                      size_t max_out_key_len,
                                      const uint8_t *their_msg,
                                      size_t their_msg_len);


#if defined(__cplusplus)
}  /* extern C */

extern "C++" {

namespace bssl {

BORINGSSL_MAKE_DELETER(SPAKE2_CTX, SPAKE2_CTX_free)

}  // namespace bssl

}  /* extern C++ */

#endif

#endif  /* OPENSSL_HEADER_CURVE25519_H */