comparison ed25519.c @ 1739:13d834efc376 fuzz

merge from main
author Matt Johnston <matt@ucc.asn.au>
date Thu, 15 Oct 2020 19:55:15 +0800
parents 93dcc97c3f3f
children 35d504d59c05
comparison
equal deleted inserted replaced
1562:768ebf737aa0 1739:13d834efc376
1 /*
2 * Dropbear - a SSH2 server
3 *
4 * Copyright (c) 2002,2003 Matt Johnston
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE. */
24
25 /* Perform Ed25519 operations on data, including reading keys, signing and
26 * verification. */
27
28 #include "includes.h"
29 #include "dbutil.h"
30 #include "buffer.h"
31 #include "ssh.h"
32 #include "curve25519.h"
33 #include "ed25519.h"
34
35 #if DROPBEAR_ED25519
36
37 /* Load a public ed25519 key from a buffer, initialising the values.
38 * The key will have the same format as buf_put_ed25519_key.
39 * These should be freed with ed25519_key_free.
40 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
41 int buf_get_ed25519_pub_key(buffer *buf, dropbear_ed25519_key *key) {
42
43 unsigned int len;
44
45 TRACE(("enter buf_get_ed25519_pub_key"))
46 dropbear_assert(key != NULL);
47
48 buf_incrpos(buf, 4+SSH_SIGNKEY_ED25519_LEN); /* int + "ssh-ed25519" */
49
50 len = buf_getint(buf);
51 if (len != CURVE25519_LEN || buf->len - buf->pos < len) {
52 TRACE(("leave buf_get_ed25519_pub_key: failure"))
53 return DROPBEAR_FAILURE;
54 }
55
56 m_burn(key->priv, CURVE25519_LEN);
57 memcpy(key->pub, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
58 buf_incrpos(buf, CURVE25519_LEN);
59
60 TRACE(("leave buf_get_ed25519_pub_key: success"))
61 return DROPBEAR_SUCCESS;
62 }
63
64 /* Same as buf_get_ed25519_pub_key, but reads private key at the end.
65 * Loads a public and private ed25519 key from a buffer
66 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
67 int buf_get_ed25519_priv_key(buffer *buf, dropbear_ed25519_key *key) {
68
69 unsigned int len;
70
71 TRACE(("enter buf_get_ed25519_priv_key"))
72 dropbear_assert(key != NULL);
73
74 buf_incrpos(buf, 4+SSH_SIGNKEY_ED25519_LEN); /* int + "ssh-ed25519" */
75
76 len = buf_getint(buf);
77 if (len != CURVE25519_LEN*2 || buf->len - buf->pos < len) {
78 TRACE(("leave buf_get_ed25519_priv_key: failure"))
79 return DROPBEAR_FAILURE;
80 }
81
82 memcpy(key->priv, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
83 buf_incrpos(buf, CURVE25519_LEN);
84 memcpy(key->pub, buf_getptr(buf, CURVE25519_LEN), CURVE25519_LEN);
85 buf_incrpos(buf, CURVE25519_LEN);
86
87 TRACE(("leave buf_get_ed25519_priv_key: success"))
88 return DROPBEAR_SUCCESS;
89 }
90
91 /* Clear and free the memory used by a public or private key */
92 void ed25519_key_free(dropbear_ed25519_key *key) {
93
94 TRACE2(("enter ed25519_key_free"))
95
96 if (key == NULL) {
97 TRACE2(("leave ed25519_key_free: key == NULL"))
98 return;
99 }
100 m_burn(key->priv, CURVE25519_LEN);
101 m_free(key);
102
103 TRACE2(("leave ed25519_key_free"))
104 }
105
106 /* Put the public ed25519 key into the buffer in the required format */
107 void buf_put_ed25519_pub_key(buffer *buf, const dropbear_ed25519_key *key) {
108
109 TRACE(("enter buf_put_ed25519_pub_key"))
110 dropbear_assert(key != NULL);
111
112 buf_putstring(buf, SSH_SIGNKEY_ED25519, SSH_SIGNKEY_ED25519_LEN);
113 buf_putstring(buf, key->pub, CURVE25519_LEN);
114
115 TRACE(("leave buf_put_ed25519_pub_key"))
116 }
117
118 /* Put the public and private ed25519 key into the buffer in the required format */
119 void buf_put_ed25519_priv_key(buffer *buf, const dropbear_ed25519_key *key) {
120
121 TRACE(("enter buf_put_ed25519_priv_key"))
122 dropbear_assert(key != NULL);
123
124 buf_putstring(buf, SSH_SIGNKEY_ED25519, SSH_SIGNKEY_ED25519_LEN);
125 buf_putint(buf, CURVE25519_LEN*2);
126 buf_putbytes(buf, key->priv, CURVE25519_LEN);
127 buf_putbytes(buf, key->pub, CURVE25519_LEN);
128
129 TRACE(("leave buf_put_ed25519_priv_key"))
130 }
131
132 /* Sign the data presented with key, writing the signature contents
133 * to the buffer */
134 void buf_put_ed25519_sign(buffer* buf, const dropbear_ed25519_key *key, const buffer *data_buf) {
135
136 unsigned char s[64];
137 unsigned long slen = sizeof(s);
138
139 TRACE(("enter buf_put_ed25519_sign"))
140 dropbear_assert(key != NULL);
141
142 dropbear_ed25519_sign(data_buf->data, data_buf->len, s, &slen, key->priv, key->pub);
143 buf_putstring(buf, SSH_SIGNKEY_ED25519, SSH_SIGNKEY_ED25519_LEN);
144 buf_putstring(buf, s, slen);
145
146 TRACE(("leave buf_put_ed25519_sign"))
147 }
148
149 #if DROPBEAR_SIGNKEY_VERIFY
150 /* Verify a signature in buf, made on data by the key given.
151 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
152 int buf_ed25519_verify(buffer *buf, const dropbear_ed25519_key *key, const buffer *data_buf) {
153
154 int ret = DROPBEAR_FAILURE;
155 unsigned char *s;
156 unsigned long slen;
157
158 TRACE(("enter buf_ed25519_verify"))
159 dropbear_assert(key != NULL);
160
161 slen = buf_getint(buf);
162 if (slen != 64 || buf->len - buf->pos < slen) {
163 TRACE(("leave buf_ed25519_verify: bad size"))
164 goto out;
165 }
166 s = buf_getptr(buf, slen);
167
168 if (dropbear_ed25519_verify(data_buf->data, data_buf->len,
169 s, slen, key->pub) == 0) {
170 /* signature is valid */
171 TRACE(("leave buf_ed25519_verify: success!"))
172 ret = DROPBEAR_SUCCESS;
173 }
174
175 out:
176 TRACE(("leave buf_ed25519_verify: ret %d", ret))
177 return ret;
178 }
179
180 #endif /* DROPBEAR_SIGNKEY_VERIFY */
181
182 #endif /* DROPBEAR_ED25519 */