Coverage Report

Created: 2026-09-14 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/curl/lib/curl_ed25519.c
Line
Count
Source
1
/***************************************************************************
2
 *                                  _   _ ____  _
3
 *  Project                     ___| | | |  _ \| |
4
 *                             / __| | | | |_) | |
5
 *                            | (__| |_| |  _ <| |___
6
 *                             \___|\___/|_| \_\_____|
7
 *
8
 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9
 *
10
 * This software is licensed as described in the file COPYING, which
11
 * you should have received as part of this distribution. The terms
12
 * are also available at https://curl.se/docs/copyright.html.
13
 *
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15
 * copies of the Software, and permit persons to whom the Software is
16
 * furnished to do so, under the terms of the COPYING file.
17
 *
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
 * KIND, either express or implied.
20
 *
21
 * SPDX-License-Identifier: curl
22
 *
23
 ***************************************************************************/
24
#include "curl_setup.h"
25
26
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HTTPSIG)
27
28
/* Please keep the SSL backend-specific #if branches in this order:
29
 *
30
 * 1. USE_OPENSSL
31
 * 2. USE_WOLFSSL
32
 * 3. USE_GNUTLS
33
 * 4. USE_MBEDTLS
34
 */
35
36
#include "curl_ed25519.h"
37
38
#ifdef USE_WOLFSSL
39
#include <wolfssl/options.h>
40
#include <wolfssl/wolfcrypt/settings.h>
41
#endif
42
43
#ifdef USE_OPENSSL
44
#include <openssl/evp.h>
45
46
CURLcode Curl_ed25519_sign(const unsigned char *key, size_t keylen,
47
                           const unsigned char *msg, size_t msglen,
48
                           unsigned char *sig, size_t *siglen)
49
0
{
50
0
  EVP_PKEY *pkey;
51
0
  EVP_MD_CTX *mdctx;
52
0
  size_t slen;
53
0
  int rc;
54
55
0
  if(keylen != CURL_ED25519_KEYLEN)
56
0
    return CURLE_BAD_FUNCTION_ARGUMENT;
57
58
0
  pkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_ED25519, NULL, key, keylen);
59
0
  if(!pkey)
60
0
    return CURLE_AUTH_ERROR;
61
62
0
  mdctx = EVP_MD_CTX_new();
63
0
  if(!mdctx) {
64
0
    EVP_PKEY_free(pkey);
65
0
    return CURLE_OUT_OF_MEMORY;
66
0
  }
67
68
0
  rc = EVP_DigestSignInit(mdctx, NULL, NULL, NULL, pkey);
69
0
  if(rc != 1) {
70
0
    EVP_MD_CTX_free(mdctx);
71
0
    EVP_PKEY_free(pkey);
72
0
    return CURLE_AUTH_ERROR;
73
0
  }
74
75
0
  slen = CURL_ED25519_SIGLEN;
76
0
  rc = EVP_DigestSign(mdctx, sig, &slen, msg, msglen);
77
78
0
  EVP_MD_CTX_free(mdctx);
79
0
  EVP_PKEY_free(pkey);
80
81
0
  if(rc != 1)
82
0
    return CURLE_AUTH_ERROR;
83
84
0
  *siglen = slen;
85
0
  return CURLE_OK;
86
0
}
87
88
#elif defined(USE_WOLFSSL) && \
89
  (defined(HAVE_ED25519) || defined(WOLFSSL_CURVE25519_USE_ED25519)) && \
90
  defined(HAVE_ED25519_KEY_IMPORT) && defined(HAVE_ED25519_SIGN)
91
#include <wolfssl/wolfcrypt/ed25519.h>
92
#include <wolfssl/wolfcrypt/error-crypt.h>
93
#include <wolfssl/wolfcrypt/random.h>
94
95
CURLcode Curl_ed25519_sign(const unsigned char *key, size_t keylen,
96
                           const unsigned char *msg, size_t msglen,
97
                           unsigned char *sig, size_t *siglen)
98
{
99
  int ret;
100
  ed25519_key edkey;
101
  word32 outlen;
102
  unsigned char pubkey[ED25519_PUB_KEY_SIZE];
103
104
  if(keylen != ED25519_KEY_SIZE)
105
    return CURLE_BAD_FUNCTION_ARGUMENT;
106
107
  ret = wc_ed25519_init(&edkey);
108
  if(ret)
109
    return CURLE_AUTH_ERROR;
110
111
  ret = wc_ed25519_import_private_only(key, ED25519_KEY_SIZE, &edkey);
112
  if(ret)
113
    goto fail;
114
115
  ret = wc_ed25519_make_public(&edkey, pubkey, ED25519_PUB_KEY_SIZE);
116
  if(ret)
117
    goto fail;
118
119
  ret = wc_ed25519_import_private_key(key, ED25519_KEY_SIZE,
120
                                      pubkey, ED25519_PUB_KEY_SIZE, &edkey);
121
  if(ret)
122
    goto fail;
123
124
  outlen = ED25519_SIG_SIZE;
125
  ret = wc_ed25519_sign_msg(msg, (word32)msglen, sig, &outlen, &edkey);
126
  if(ret)
127
    goto fail;
128
129
  *siglen = (size_t)outlen;
130
  wc_ed25519_free(&edkey);
131
  return CURLE_OK;
132
133
fail:
134
  wc_ed25519_free(&edkey);
135
  return CURLE_AUTH_ERROR;
136
}
137
138
#elif defined(USE_GNUTLS)
139
#include <nettle/eddsa.h>
140
141
CURLcode Curl_ed25519_sign(const unsigned char *key, size_t keylen,
142
                           const unsigned char *msg, size_t msglen,
143
                           unsigned char *sig, size_t *siglen)
144
{
145
  uint8_t pubkey[ED25519_KEY_SIZE];
146
147
  if(keylen != ED25519_KEY_SIZE)
148
    return CURLE_BAD_FUNCTION_ARGUMENT;
149
150
  nettle_ed25519_sha512_public_key(pubkey, key);
151
152
  nettle_ed25519_sha512_sign(pubkey, key, msglen, msg, sig);
153
  *siglen = CURL_ED25519_SIGLEN;
154
155
  return CURLE_OK;
156
}
157
158
#else /* no Ed25519-capable backend */
159
160
CURLcode Curl_ed25519_sign(const unsigned char *key, size_t keylen,
161
                           const unsigned char *msg, size_t msglen,
162
                           unsigned char *sig, size_t *siglen)
163
{
164
  (void)key;
165
  (void)keylen;
166
  (void)msg;
167
  (void)msglen;
168
  (void)sig;
169
  (void)siglen;
170
  return CURLE_NOT_BUILT_IN;
171
}
172
173
#endif /* Ed25519 backends */
174
175
#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_HTTPSIG */