1 /*
2  * Copyright (c) 2019 Markus Friedl
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include "includes.h"
18 
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <stddef.h>
24 #include <stdarg.h>
25 
26 #include "crypto_api.h"
27 
28 #include <openssl/opensslv.h>
29 #include <openssl/crypto.h>
30 #include <openssl/evp.h>
31 #include <openssl/bn.h>
32 #include <openssl/ec.h>
33 #include <openssl/ecdsa.h>
34 #include <openssl/pem.h>
35 
36 /* #define SK_DEBUG 1 */
37 
38 /* Compatibility with OpenSSH 1.0.x */
39 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
40 #define ECDSA_SIG_get0(sig, pr, ps) \
41 	do { \
42 		(*pr) = sig->r; \
43 		(*ps) = sig->s; \
44 	} while (0)
45 #endif
46 
47 #define SK_VERSION_MAJOR	0x00030000 /* current API version */
48 
49 /* Flags */
50 #define SK_USER_PRESENCE_REQD	0x01
51 
52 /* Algs */
53 #define	SK_ECDSA		0x00
54 #define	SK_ED25519		0x01
55 
56 /* Error codes */
57 #define SSH_SK_ERR_GENERAL		-1
58 #define SSH_SK_ERR_UNSUPPORTED		-2
59 #define SSH_SK_ERR_PIN_REQUIRED		-3
60 
61 struct sk_enroll_response {
62 	uint8_t *public_key;
63 	size_t public_key_len;
64 	uint8_t *key_handle;
65 	size_t key_handle_len;
66 	uint8_t *signature;
67 	size_t signature_len;
68 	uint8_t *attestation_cert;
69 	size_t attestation_cert_len;
70 };
71 
72 struct sk_sign_response {
73 	uint8_t flags;
74 	uint32_t counter;
75 	uint8_t *sig_r;
76 	size_t sig_r_len;
77 	uint8_t *sig_s;
78 	size_t sig_s_len;
79 };
80 
81 struct sk_resident_key {
82 	uint8_t alg;
83 	size_t slot;
84 	char *application;
85 	struct sk_enroll_response key;
86 };
87 
88 /* Return the version of the middleware API */
89 uint32_t sk_api_version(void);
90 
91 /* Enroll a U2F key (private key generation) */
92 int sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len,
93     const char *application, uint8_t flags, const char *pin,
94     struct sk_enroll_response **enroll_response);
95 
96 /* Sign a challenge */
97 int sk_sign(int alg, const uint8_t *message, size_t message_len,
98     const char *application, const uint8_t *key_handle, size_t key_handle_len,
99     uint8_t flags, const char *pin, struct sk_sign_response **sign_response);
100 
101 /* Enumerate all resident keys */
102 int sk_load_resident_keys(const char *pin,
103     struct sk_resident_key ***rks, size_t *nrks);
104 
105 static void skdebug(const char *func, const char *fmt, ...)
106     __attribute__((__format__ (printf, 2, 3)));
107 
108 static void
109 skdebug(const char *func, const char *fmt, ...)
110 {
111 #if defined(SK_DEBUG)
112 	va_list ap;
113 
114 	va_start(ap, fmt);
115 	fprintf(stderr, "sk-dummy %s: ", func);
116 	vfprintf(stderr, fmt, ap);
117 	fputc('\n', stderr);
118 	va_end(ap);
119 #else
120 	(void)func; /* XXX */
121 	(void)fmt; /* XXX */
122 #endif
123 }
124 
125 uint32_t
126 sk_api_version(void)
127 {
128 	return SK_VERSION_MAJOR;
129 }
130 
131 static int
132 pack_key_ecdsa(struct sk_enroll_response *response)
133 {
134 #ifdef OPENSSL_HAS_ECC
135 	EC_KEY *key = NULL;
136 	const EC_GROUP *g;
137 	const EC_POINT *q;
138 	int ret = -1;
139 	long privlen;
140 	BIO *bio = NULL;
141 	char *privptr;
142 
143 	response->public_key = NULL;
144 	response->public_key_len = 0;
145 	response->key_handle = NULL;
146 	response->key_handle_len = 0;
147 
148 	if ((key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)) == NULL) {
149 		skdebug(__func__, "EC_KEY_new_by_curve_name");
150 		goto out;
151 	}
152 	if (EC_KEY_generate_key(key) != 1) {
153 		skdebug(__func__, "EC_KEY_generate_key");
154 		goto out;
155 	}
156 	EC_KEY_set_asn1_flag(key, OPENSSL_EC_NAMED_CURVE);
157 	if ((bio = BIO_new(BIO_s_mem())) == NULL ||
158 	    (g = EC_KEY_get0_group(key)) == NULL ||
159 	    (q = EC_KEY_get0_public_key(key)) == NULL) {
160 		skdebug(__func__, "couldn't get key parameters");
161 		goto out;
162 	}
163 	response->public_key_len = EC_POINT_point2oct(g, q,
164 	    POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
165 	if (response->public_key_len == 0 || response->public_key_len > 2048) {
166 		skdebug(__func__, "bad pubkey length %zu",
167 		    response->public_key_len);
168 		goto out;
169 	}
170 	if ((response->public_key = malloc(response->public_key_len)) == NULL) {
171 		skdebug(__func__, "malloc pubkey failed");
172 		goto out;
173 	}
174 	if (EC_POINT_point2oct(g, q, POINT_CONVERSION_UNCOMPRESSED,
175 	    response->public_key, response->public_key_len, NULL) == 0) {
176 		skdebug(__func__, "EC_POINT_point2oct failed");
177 		goto out;
178 	}
179 	/* Key handle contains PEM encoded private key */
180 	if (!PEM_write_bio_ECPrivateKey(bio, key, NULL, NULL, 0, NULL, NULL)) {
181 		skdebug(__func__, "PEM_write_bio_ECPrivateKey failed");
182 		goto out;
183 	}
184 	if ((privlen = BIO_get_mem_data(bio, &privptr)) <= 0) {
185 		skdebug(__func__, "BIO_get_mem_data failed");
186 		goto out;
187 	}
188 	if ((response->key_handle = malloc(privlen)) == NULL) {
189 		skdebug(__func__, "malloc key_handle failed");
190 		goto out;
191 	}
192 	response->key_handle_len = (size_t)privlen;
193 	memcpy(response->key_handle, privptr, response->key_handle_len);
194 	/* success */
195 	ret = 0;
196  out:
197 	if (ret != 0) {
198 		if (response->public_key != NULL) {
199 			memset(response->public_key, 0,
200 			    response->public_key_len);
201 			free(response->public_key);
202 			response->public_key = NULL;
203 		}
204 		if (response->key_handle != NULL) {
205 			memset(response->key_handle, 0,
206 			    response->key_handle_len);
207 			free(response->key_handle);
208 			response->key_handle = NULL;
209 		}
210 	}
211 	BIO_free(bio);
212 	EC_KEY_free(key);
213 	return ret;
214 #else
215 	return -1;
216 #endif
217 }
218 
219 static int
220 pack_key_ed25519(struct sk_enroll_response *response)
221 {
222 	int ret = -1;
223 	u_char pk[crypto_sign_ed25519_PUBLICKEYBYTES];
224 	u_char sk[crypto_sign_ed25519_SECRETKEYBYTES];
225 
226 	response->public_key = NULL;
227 	response->public_key_len = 0;
228 	response->key_handle = NULL;
229 	response->key_handle_len = 0;
230 
231 	memset(pk, 0, sizeof(pk));
232 	memset(sk, 0, sizeof(sk));
233 	crypto_sign_ed25519_keypair(pk, sk);
234 
235 	response->public_key_len = sizeof(pk);
236 	if ((response->public_key = malloc(response->public_key_len)) == NULL) {
237 		skdebug(__func__, "malloc pubkey failed");
238 		goto out;
239 	}
240 	memcpy(response->public_key, pk, sizeof(pk));
241 	/* Key handle contains sk */
242 	response->key_handle_len = sizeof(sk);
243 	if ((response->key_handle = malloc(response->key_handle_len)) == NULL) {
244 		skdebug(__func__, "malloc key_handle failed");
245 		goto out;
246 	}
247 	memcpy(response->key_handle, sk, sizeof(sk));
248 	/* success */
249 	ret = 0;
250  out:
251 	if (ret != 0)
252 		free(response->public_key);
253 	return ret;
254 }
255 
256 int
257 sk_enroll(int alg, const uint8_t *challenge, size_t challenge_len,
258     const char *application, uint8_t flags, const char *pin,
259     struct sk_enroll_response **enroll_response)
260 {
261 	struct sk_enroll_response *response = NULL;
262 	int ret = -1;
263 
264 	(void)flags; /* XXX; unused */
265 
266 	if (enroll_response == NULL) {
267 		skdebug(__func__, "enroll_response == NULL");
268 		goto out;
269 	}
270 	*enroll_response = NULL;
271 	if ((response = calloc(1, sizeof(*response))) == NULL) {
272 		skdebug(__func__, "calloc response failed");
273 		goto out;
274 	}
275 	switch(alg) {
276 	case SK_ECDSA:
277 		if (pack_key_ecdsa(response) != 0)
278 			goto out;
279 		break;
280 	case SK_ED25519:
281 		if (pack_key_ed25519(response) != 0)
282 			goto out;
283 		break;
284 	default:
285 		skdebug(__func__, "unsupported key type %d", alg);
286 		return -1;
287 	}
288 	/* Have to return something here */
289 	if ((response->signature = calloc(1, 1)) == NULL) {
290 		skdebug(__func__, "calloc signature failed");
291 		goto out;
292 	}
293 	response->signature_len = 0;
294 
295 	*enroll_response = response;
296 	response = NULL;
297 	ret = 0;
298  out:
299 	if (response != NULL) {
300 		free(response->public_key);
301 		free(response->key_handle);
302 		free(response->signature);
303 		free(response->attestation_cert);
304 		free(response);
305 	}
306 	return ret;
307 }
308 
309 static void
310 dump(const char *preamble, const void *sv, size_t l)
311 {
312 #ifdef SK_DEBUG
313 	const u_char *s = (const u_char *)sv;
314 	size_t i;
315 
316 	fprintf(stderr, "%s (len %zu):\n", preamble, l);
317 	for (i = 0; i < l; i++) {
318 		if (i % 16 == 0)
319 			fprintf(stderr, "%04zu: ", i);
320 		fprintf(stderr, "%02x", s[i]);
321 		if (i % 16 == 15 || i == l - 1)
322 			fprintf(stderr, "\n");
323 	}
324 #endif
325 }
326 
327 static int
328 sig_ecdsa(const uint8_t *message, size_t message_len,
329     const char *application, uint32_t counter, uint8_t flags,
330     const uint8_t *key_handle, size_t key_handle_len,
331     struct sk_sign_response *response)
332 {
333 #ifdef OPENSSL_HAS_ECC
334 	ECDSA_SIG *sig = NULL;
335 	const BIGNUM *sig_r, *sig_s;
336 	int ret = -1;
337 	BIO *bio = NULL;
338 	EVP_PKEY *pk = NULL;
339 	EC_KEY *ec = NULL;
340 	SHA256_CTX ctx;
341 	uint8_t	apphash[SHA256_DIGEST_LENGTH];
342 	uint8_t	sighash[SHA256_DIGEST_LENGTH];
343 	uint8_t countbuf[4];
344 
345 	/* Decode EC_KEY from key handle */
346 	if ((bio = BIO_new(BIO_s_mem())) == NULL ||
347 	    BIO_write(bio, key_handle, key_handle_len) != (int)key_handle_len) {
348 		skdebug(__func__, "BIO setup failed");
349 		goto out;
350 	}
351 	if ((pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, "")) == NULL) {
352 		skdebug(__func__, "PEM_read_bio_PrivateKey failed");
353 		goto out;
354 	}
355 	if (EVP_PKEY_base_id(pk) != EVP_PKEY_EC) {
356 		skdebug(__func__, "Not an EC key: %d", EVP_PKEY_base_id(pk));
357 		goto out;
358 	}
359 	if ((ec = EVP_PKEY_get1_EC_KEY(pk)) == NULL) {
360 		skdebug(__func__, "EVP_PKEY_get1_EC_KEY failed");
361 		goto out;
362 	}
363 	/* Expect message to be pre-hashed */
364 	if (message_len != SHA256_DIGEST_LENGTH) {
365 		skdebug(__func__, "bad message len %zu", message_len);
366 		goto out;
367 	}
368 	/* Prepare data to be signed */
369 	dump("message", message, message_len);
370 	SHA256_Init(&ctx);
371 	SHA256_Update(&ctx, application, strlen(application));
372 	SHA256_Final(apphash, &ctx);
373 	dump("apphash", apphash, sizeof(apphash));
374 	countbuf[0] = (counter >> 24) & 0xff;
375 	countbuf[1] = (counter >> 16) & 0xff;
376 	countbuf[2] = (counter >> 8) & 0xff;
377 	countbuf[3] = counter & 0xff;
378 	dump("countbuf", countbuf, sizeof(countbuf));
379 	dump("flags", &flags, sizeof(flags));
380 	SHA256_Init(&ctx);
381 	SHA256_Update(&ctx, apphash, sizeof(apphash));
382 	SHA256_Update(&ctx, &flags, sizeof(flags));
383 	SHA256_Update(&ctx, countbuf, sizeof(countbuf));
384 	SHA256_Update(&ctx, message, message_len);
385 	SHA256_Final(sighash, &ctx);
386 	dump("sighash", sighash, sizeof(sighash));
387 	/* create and encode signature */
388 	if ((sig = ECDSA_do_sign(sighash, sizeof(sighash), ec)) == NULL) {
389 		skdebug(__func__, "ECDSA_do_sign failed");
390 		goto out;
391 	}
392 	ECDSA_SIG_get0(sig, &sig_r, &sig_s);
393 	response->sig_r_len = BN_num_bytes(sig_r);
394 	response->sig_s_len = BN_num_bytes(sig_s);
395 	if ((response->sig_r = calloc(1, response->sig_r_len)) == NULL ||
396 	    (response->sig_s = calloc(1, response->sig_s_len)) == NULL) {
397 		skdebug(__func__, "calloc signature failed");
398 		goto out;
399 	}
400 	BN_bn2bin(sig_r, response->sig_r);
401 	BN_bn2bin(sig_s, response->sig_s);
402 	ret = 0;
403  out:
404 	explicit_bzero(&ctx, sizeof(ctx));
405 	explicit_bzero(&apphash, sizeof(apphash));
406 	explicit_bzero(&sighash, sizeof(sighash));
407 	ECDSA_SIG_free(sig);
408 	if (ret != 0) {
409 		free(response->sig_r);
410 		free(response->sig_s);
411 		response->sig_r = NULL;
412 		response->sig_s = NULL;
413 	}
414 	BIO_free(bio);
415 	EC_KEY_free(ec);
416 	EVP_PKEY_free(pk);
417 	return ret;
418 #else
419 	return -1;
420 #endif
421 }
422 
423 static int
424 sig_ed25519(const uint8_t *message, size_t message_len,
425     const char *application, uint32_t counter, uint8_t flags,
426     const uint8_t *key_handle, size_t key_handle_len,
427     struct sk_sign_response *response)
428 {
429 	size_t o;
430 	int ret = -1;
431 	SHA256_CTX ctx;
432 	uint8_t	apphash[SHA256_DIGEST_LENGTH];
433 	uint8_t signbuf[sizeof(apphash) + sizeof(flags) +
434 	    sizeof(counter) + SHA256_DIGEST_LENGTH];
435 	uint8_t sig[crypto_sign_ed25519_BYTES + sizeof(signbuf)];
436 	unsigned long long smlen;
437 
438 	if (key_handle_len != crypto_sign_ed25519_SECRETKEYBYTES) {
439 		skdebug(__func__, "bad key handle length %zu", key_handle_len);
440 		goto out;
441 	}
442 	/* Expect message to be pre-hashed */
443 	if (message_len != SHA256_DIGEST_LENGTH) {
444 		skdebug(__func__, "bad message len %zu", message_len);
445 		goto out;
446 	}
447 	/* Prepare data to be signed */
448 	dump("message", message, message_len);
449 	SHA256_Init(&ctx);
450 	SHA256_Update(&ctx, application, strlen(application));
451 	SHA256_Final(apphash, &ctx);
452 	dump("apphash", apphash, sizeof(apphash));
453 
454 	memcpy(signbuf, apphash, sizeof(apphash));
455 	o = sizeof(apphash);
456 	signbuf[o++] = flags;
457 	signbuf[o++] = (counter >> 24) & 0xff;
458 	signbuf[o++] = (counter >> 16) & 0xff;
459 	signbuf[o++] = (counter >> 8) & 0xff;
460 	signbuf[o++] = counter & 0xff;
461 	memcpy(signbuf + o, message, message_len);
462 	o += message_len;
463 	if (o != sizeof(signbuf)) {
464 		skdebug(__func__, "bad sign buf len %zu, expected %zu",
465 		    o, sizeof(signbuf));
466 		goto out;
467 	}
468 	dump("signbuf", signbuf, sizeof(signbuf));
469 	/* create and encode signature */
470 	smlen = sizeof(signbuf);
471 	if (crypto_sign_ed25519(sig, &smlen, signbuf, sizeof(signbuf),
472 	    key_handle) != 0) {
473 		skdebug(__func__, "crypto_sign_ed25519 failed");
474 		goto out;
475 	}
476 	if (smlen <= sizeof(signbuf)) {
477 		skdebug(__func__, "bad sign smlen %llu, expected min %zu",
478 		    smlen, sizeof(signbuf) + 1);
479 		goto out;
480 	}
481 	response->sig_r_len = (size_t)(smlen - sizeof(signbuf));
482 	if ((response->sig_r = calloc(1, response->sig_r_len)) == NULL) {
483 		skdebug(__func__, "calloc signature failed");
484 		goto out;
485 	}
486 	memcpy(response->sig_r, sig, response->sig_r_len);
487 	dump("sig_r", response->sig_r, response->sig_r_len);
488 	ret = 0;
489  out:
490 	explicit_bzero(&ctx, sizeof(ctx));
491 	explicit_bzero(&apphash, sizeof(apphash));
492 	explicit_bzero(&signbuf, sizeof(signbuf));
493 	explicit_bzero(&sig, sizeof(sig));
494 	if (ret != 0) {
495 		free(response->sig_r);
496 		response->sig_r = NULL;
497 	}
498 	return ret;
499 }
500 
501 int
502 sk_sign(int alg, const uint8_t *message, size_t message_len,
503     const char *application,
504     const uint8_t *key_handle, size_t key_handle_len,
505     uint8_t flags, const char *pin, struct sk_sign_response **sign_response)
506 {
507 	struct sk_sign_response *response = NULL;
508 	int ret = -1;
509 
510 	if (sign_response == NULL) {
511 		skdebug(__func__, "sign_response == NULL");
512 		goto out;
513 	}
514 	*sign_response = NULL;
515 	if ((response = calloc(1, sizeof(*response))) == NULL) {
516 		skdebug(__func__, "calloc response failed");
517 		goto out;
518 	}
519 	response->flags = flags;
520 	response->counter = 0x12345678;
521 	switch(alg) {
522 	case SK_ECDSA:
523 		if (sig_ecdsa(message, message_len, application,
524 		    response->counter, flags, key_handle, key_handle_len,
525 		    response) != 0)
526 			goto out;
527 		break;
528 	case SK_ED25519:
529 		if (sig_ed25519(message, message_len, application,
530 		    response->counter, flags, key_handle, key_handle_len,
531 		    response) != 0)
532 			goto out;
533 		break;
534 	default:
535 		skdebug(__func__, "unsupported key type %d", alg);
536 		return -1;
537 	}
538 	*sign_response = response;
539 	response = NULL;
540 	ret = 0;
541  out:
542 	if (response != NULL) {
543 		free(response->sig_r);
544 		free(response->sig_s);
545 		free(response);
546 	}
547 	return ret;
548 }
549 
550 int
551 sk_load_resident_keys(const char *pin,
552     struct sk_resident_key ***rks, size_t *nrks)
553 {
554 	return SSH_SK_ERR_UNSUPPORTED;
555 }
556