EVP_PKEY*
ldns_ed4482pkey_raw(const unsigned char* key, size_t keylen)
{
- const unsigned char* pp = key; /* pp gets modified by o2i() */
+ /* ASN1 for ED448 is 3043300506032b6571033a00 <57byteskey> */
+ uint8_t pre[] = {0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65,
+ 0x71, 0x03, 0x3a, 0x00};
+ int pre_len = 12;
+ uint8_t buf[256];
EVP_PKEY *evp_key;
- EC_KEY *ec;
- if(keylen != 57)
+ /* pp gets modified by d2i() */
+ const unsigned char* pp = (unsigned char*)buf;
+ if(keylen != 57 || keylen + pre_len > sizeof(buf))
return NULL; /* wrong length */
- ec = EC_KEY_new_by_curve_name(NID_ED448);
- if(!ec) return NULL;
- if(!o2i_ECPublicKey(&ec, &pp, (int)keylen)) {
- EC_KEY_free(ec);
- return NULL;
- }
- evp_key = EVP_PKEY_new();
- if(!evp_key) {
- EC_KEY_free(ec);
- return NULL;
- }
- if (!EVP_PKEY_assign_EC_KEY(evp_key, ec)) {
- EVP_PKEY_free(evp_key);
- EC_KEY_free(ec);
- return NULL;
- }
+ memmove(buf, pre, pre_len);
+ memmove(buf+pre_len, key, keylen);
+ evp_key = d2i_PUBKEY(NULL, &pp, (int)(pre_len+keylen));
return evp_key;
}
}
#endif
-#if defined(USE_ED448)
-/* debug printout routine */
-static void ed448_print_hex(const char* str, uint8_t* d, int len)
-{
- const char hex[] = "0123456789abcdef";
- int i;
- printf("%s [len=%d]: ", str, len);
- for(i=0; i<len; i++) {
- int x = (d[i]&0xf0)>>4;
- int y = (d[i]&0x0f);
- printf("%c%c", hex[x], hex[y]);
- }
- printf("\n");
-}
-#endif
-
#if defined(HAVE_SSL) && defined(USE_ED448)
static ldns_status
ldns_ed448_key2buffer_str(ldns_buffer *output, EVP_PKEY *p)
ldns_buffer_printf(output, "PrivateKey: ");
ret = i2d_PrivateKey(p, &pp);
- /* printout hex to find length of ASN */
- ed448_print_hex("ED448 privkey i2d", pp, ret);
- /* some-ASN (??) + 56byte key */
- if(ret != 16 + 56) {
+ /* some-ASN + 57byte key */
+ if(ret != 16 + 57) {
OPENSSL_free(pp);
return LDNS_STATUS_ERR;
}
}
#endif
-#if defined(USE_ED448)
-/* debug printout routine */
-static void print_hex(const char* str, uint8_t* d, int len)
-{
- const char hex[] = "0123456789abcdef";
- int i;
- printf("%s [len=%d]: ", str, len);
- for(i=0; i<len; i++) {
- int x = (d[i]&0xf0)>>4;
- int y = (d[i]&0x0f);
- printf("%c%c", hex[x], hex[y]);
- }
- printf("\n");
-}
-#endif
-
#ifdef USE_ED448
/** turn private key buffer into EC_KEY structure */
static EVP_PKEY*
const unsigned char* pp;
uint8_t buf[256];
int buflen = 0;
- uint8_t pre[] = {0x30, 0x4b, 0x02, 0x01, 0x01, 0x04, 0x39};
- int pre_len = 7;
- uint8_t post[] = {0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
- 0x01, 0xda, 0x47, 0x0f, 0x02};
- int post_len = 13;
- int i;
- /* ASN looks like this for ED25519
- * And for ED448, the parameters are ...02 instead of ...01
- * For ED25519 it was:
- * 30320201010420 <32byteskey>
- * andparameters a00b06092b06010401da470f01
- * (noparameters, preamble is 30250201010420).
+ uint8_t pre[] = {0x30, 0x47, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x71, 0x04, 0x3b, 0x04, 0x39};
+ int pre_len = 16;
+ /* ASN looks like this for ED448
+ * 3047020100300506032b6571043b0439 <57bytekey>
* the key is reversed (little endian).
- *
- * For ED448 the key is 57 bytes, and that changes lengths.
- * 304b0201010439 <57bytekey> a00b06092b06010401da470f02
*/
- buflen = pre_len + plen + post_len;
+ buflen = pre_len + plen;
if((size_t)buflen > sizeof(buf))
return NULL;
memmove(buf, pre, pre_len);
- /* reverse the pkey into the buf */
- for(i=0; i<plen; i++)
- buf[pre_len+i] = pkey[plen-1-i];
- memmove(buf+pre_len+plen, post, post_len);
+ memmove(buf+pre_len, pkey, plen);
+ /* reverse the pkey into the buf - key is not reversed it seems */
+ /* for(i=0; i<plen; i++)
+ buf[pre_len+i] = pkey[plen-1-i]; */
pp = buf;
return d2i_PrivateKey(NID_ED448, NULL, &pp, buflen);
}
{
int i;
unsigned char* pp = NULL;
- unsigned len = i2d_PUBKEY(k, &pp);
- /* printout ASN format for pubkey */
- print_hex("ed448 pubkey i2d", pp, len);
- free(pp); pp = NULL;
- /* untested, not sure what the lengths are for the prefix */
- if(i2d_PUBKEY(k, &pp) != 12 + 56) {
- /* expect 12 byte(ASN header) and 56 byte(pubkey) */
+ if(i2d_PUBKEY(k, &pp) != 12 + 57) {
+ /* expect 12 byte(ASN header) and 57 byte(pubkey) */
free(pp);
return false;
}
/* omit ASN header */
- for(i=0; i<56; i++)
+ for(i=0; i<57; i++)
data[i] = pp[i+12];
free(pp);
- *size = 56;
+ *size = 57;
return true;
}
#endif /* USE_ED448 */