1 /* 2 * Copyright (c) 2019 Yubico AB. All rights reserved. 3 * Use of this source code is governed by a BSD-style 4 * license that can be found in the LICENSE file. 5 */ 6 7 #include <openssl/bn.h> 8 #include <openssl/obj_mac.h> 9 10 #include "fido.h" 11 #include "fido/eddsa.h" 12 13 #if defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10101000L 14 EVP_PKEY * 15 EVP_PKEY_new_raw_public_key(int type, ENGINE *e, const unsigned char *key, 16 size_t keylen) 17 { 18 (void)type; 19 (void)e; 20 (void)key; 21 (void)keylen; 22 23 fido_log_debug("%s: unimplemented", __func__); 24 25 return (NULL); 26 } 27 28 int 29 EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub, 30 size_t *len) 31 { 32 (void)pkey; 33 (void)pub; 34 (void)len; 35 36 fido_log_debug("%s: unimplemented", __func__); 37 38 return (0); 39 } 40 41 int 42 EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen, 43 const unsigned char *tbs, size_t tbslen) 44 { 45 (void)ctx; 46 (void)sigret; 47 (void)siglen; 48 (void)tbs; 49 (void)tbslen; 50 51 fido_log_debug("%s: unimplemented", __func__); 52 53 return (0); 54 } 55 #endif /* LIBRESSL_VERSION_NUMBER || OPENSSL_VERSION_NUMBER < 0x10101000L */ 56 57 #if OPENSSL_VERSION_NUMBER < 0x10100000L 58 EVP_MD_CTX * 59 EVP_MD_CTX_new(void) 60 { 61 fido_log_debug("%s: unimplemented", __func__); 62 63 return (NULL); 64 } 65 66 void 67 EVP_MD_CTX_free(EVP_MD_CTX *ctx) 68 { 69 (void)ctx; 70 } 71 #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ 72 73 static int 74 decode_coord(const cbor_item_t *item, void *xy, size_t xy_len) 75 { 76 if (cbor_isa_bytestring(item) == false || 77 cbor_bytestring_is_definite(item) == false || 78 cbor_bytestring_length(item) != xy_len) { 79 fido_log_debug("%s: cbor type", __func__); 80 return (-1); 81 } 82 83 memcpy(xy, cbor_bytestring_handle(item), xy_len); 84 85 return (0); 86 } 87 88 static int 89 decode_pubkey_point(const cbor_item_t *key, const cbor_item_t *val, void *arg) 90 { 91 eddsa_pk_t *k = arg; 92 93 if (cbor_isa_negint(key) == false || 94 cbor_int_get_width(key) != CBOR_INT_8) 95 return (0); /* ignore */ 96 97 switch (cbor_get_uint8(key)) { 98 case 1: /* x coordinate */ 99 return (decode_coord(val, &k->x, sizeof(k->x))); 100 } 101 102 return (0); /* ignore */ 103 } 104 105 int 106 eddsa_pk_decode(const cbor_item_t *item, eddsa_pk_t *k) 107 { 108 if (cbor_isa_map(item) == false || 109 cbor_map_is_definite(item) == false || 110 cbor_map_iter(item, k, decode_pubkey_point) < 0) { 111 fido_log_debug("%s: cbor type", __func__); 112 return (-1); 113 } 114 115 return (0); 116 } 117 118 eddsa_pk_t * 119 eddsa_pk_new(void) 120 { 121 return (calloc(1, sizeof(eddsa_pk_t))); 122 } 123 124 void 125 eddsa_pk_free(eddsa_pk_t **pkp) 126 { 127 eddsa_pk_t *pk; 128 129 if (pkp == NULL || (pk = *pkp) == NULL) 130 return; 131 132 freezero(pk, sizeof(*pk)); 133 *pkp = NULL; 134 } 135 136 int 137 eddsa_pk_from_ptr(eddsa_pk_t *pk, const void *ptr, size_t len) 138 { 139 if (len < sizeof(*pk)) 140 return (FIDO_ERR_INVALID_ARGUMENT); 141 142 memcpy(pk, ptr, sizeof(*pk)); 143 144 return (FIDO_OK); 145 } 146 147 EVP_PKEY * 148 eddsa_pk_to_EVP_PKEY(const eddsa_pk_t *k) 149 { 150 EVP_PKEY *pkey = NULL; 151 152 if ((pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, k->x, 153 sizeof(k->x))) == NULL) 154 fido_log_debug("%s: EVP_PKEY_new_raw_public_key", __func__); 155 156 return (pkey); 157 } 158 159 int 160 eddsa_pk_from_EVP_PKEY(eddsa_pk_t *pk, const EVP_PKEY *pkey) 161 { 162 size_t len = 0; 163 164 if (EVP_PKEY_get_raw_public_key(pkey, NULL, &len) != 1 || 165 len != sizeof(pk->x)) 166 return (FIDO_ERR_INTERNAL); 167 if (EVP_PKEY_get_raw_public_key(pkey, pk->x, &len) != 1 || 168 len != sizeof(pk->x)) 169 return (FIDO_ERR_INTERNAL); 170 171 return (FIDO_OK); 172 } 173