summaryrefslogtreecommitdiff
path: root/src/crypto/evp/p_ed25519.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/evp/p_ed25519.c')
-rw-r--r--src/crypto/evp/p_ed25519.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/src/crypto/evp/p_ed25519.c b/src/crypto/evp/p_ed25519.c
index 062ea458..9149afb2 100644
--- a/src/crypto/evp/p_ed25519.c
+++ b/src/crypto/evp/p_ed25519.c
@@ -16,6 +16,7 @@
#include <openssl/curve25519.h>
#include <openssl/err.h>
+#include <openssl/mem.h>
#include "internal.h"
@@ -23,6 +24,27 @@
// Ed25519 has no parameters to copy.
static int pkey_ed25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; }
+static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
+ ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY));
+ if (key == NULL) {
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (!EVP_PKEY_set_type(pkey, EVP_PKEY_ED25519)) {
+ OPENSSL_free(key);
+ return 0;
+ }
+
+ uint8_t pubkey_unused[32];
+ ED25519_keypair(pubkey_unused, key->key.priv);
+ key->has_private = 1;
+
+ OPENSSL_free(pkey->pkey.ptr);
+ pkey->pkey.ptr = key;
+ return 1;
+}
+
static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig,
size_t *siglen, const uint8_t *tbs,
size_t tbslen) {
@@ -32,12 +54,22 @@ static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig,
return 0;
}
- *siglen = 64;
if (sig == NULL) {
+ *siglen = 64;
return 1;
}
- return ED25519_sign(sig, tbs, tbslen, key->key.priv);
+ if (*siglen < 64) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (!ED25519_sign(sig, tbs, tbslen, key->key.priv)) {
+ return 0;
+ }
+
+ *siglen = 64;
+ return 1;
}
static int pkey_ed25519_verify_message(EVP_PKEY_CTX *ctx, const uint8_t *sig,
@@ -58,7 +90,7 @@ const EVP_PKEY_METHOD ed25519_pkey_meth = {
NULL /* init */,
pkey_ed25519_copy,
NULL /* cleanup */,
- NULL /* keygen */,
+ pkey_ed25519_keygen,
NULL /* sign */,
pkey_ed25519_sign_message,
NULL /* verify */,