static int x25519_keycheck(const EC_KEY *eckey) { const char *pubkey; if (eckey->pub_key == NULL) return 0; pubkey = eckey->pub_key->custom_data; if (pubkey == NULL) return 0; if (eckey->custom_data != NULL) { uint8_t tmp[EC_X25519_KEYLEN]; /* Check eckey->priv_key exists and matches eckey->custom_data */ if (eckey->priv_key == NULL) return 0; if (BN_bn2lebinpad(eckey->priv_key, tmp, EC_X25519_KEYLEN) != EC_X25519_KEYLEN || CRYPTO_memcmp(tmp, eckey->custom_data, EC_X25519_KEYLEN) != 0) { OPENSSL_cleanse(tmp, EC_X25519_KEYLEN); return 0; } X25519_public_from_private(tmp, eckey->custom_data); if (CRYPTO_memcmp(pubkey, tmp, EC_X25519_KEYLEN) == 0) return 1; return 0; } else { return 1; } }
static int x25519_set_private(EC_KEY *eckey, const BIGNUM *priv_key) { if (BN_num_bytes(priv_key) > EC_X25519_KEYLEN) return 0; if (x25519_init_private(eckey, NULL)) return 0; /* Convert BIGNUM form private key to internal format */ if (BN_bn2lebinpad(priv_key, eckey->custom_data, EC_X25519_KEYLEN) != EC_X25519_KEYLEN) return 0; return 1; }
static void write_lebn(unsigned char **out, const BIGNUM *bn, int len) { BN_bn2lebinpad(bn, *out, len); *out += len; }