Mercurial > dropbear
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 */ |