Coverage Report

Created: 2023-06-08 06:41

/src/openssl111/crypto/ec/curve448/eddsa.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
3
 * Copyright 2015-2016 Cryptography Research, Inc.
4
 *
5
 * Licensed under the OpenSSL license (the "License").  You may not use
6
 * this file except in compliance with the License.  You can obtain a copy
7
 * in the file LICENSE in the source distribution or at
8
 * https://www.openssl.org/source/license.html
9
 *
10
 * Originally written by Mike Hamburg
11
 */
12
#include <string.h>
13
#include <openssl/crypto.h>
14
#include <openssl/evp.h>
15
#include "curve448_local.h"
16
#include "word.h"
17
#include "ed448.h"
18
#include "internal/numbers.h"
19
20
12
#define COFACTOR 4
21
22
static c448_error_t oneshot_hash(uint8_t *out, size_t outlen,
23
                                 const uint8_t *in, size_t inlen)
24
12
{
25
12
    EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
26
27
12
    if (hashctx == NULL)
28
0
        return C448_FAILURE;
29
30
12
    if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
31
12
            || !EVP_DigestUpdate(hashctx, in, inlen)
32
12
            || !EVP_DigestFinalXOF(hashctx, out, outlen)) {
33
0
        EVP_MD_CTX_free(hashctx);
34
0
        return C448_FAILURE;
35
0
    }
36
37
12
    EVP_MD_CTX_free(hashctx);
38
12
    return C448_SUCCESS;
39
12
}
40
41
static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES])
42
12
{
43
12
    secret_scalar_ser[0] &= -COFACTOR;
44
12
    secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 1] = 0;
45
12
    secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 2] |= 0x80;
46
12
}
47
48
static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed,
49
                                       uint8_t for_prehash,
50
                                       const uint8_t *context,
51
                                       size_t context_len)
52
0
{
53
#ifdef CHARSET_EBCDIC
54
    const char dom_s[] = {0x53, 0x69, 0x67, 0x45,
55
                          0x64, 0x34, 0x34, 0x38, 0x00};
56
#else
57
0
    const char dom_s[] = "SigEd448";
58
0
#endif
59
0
    uint8_t dom[2];
60
61
0
    if (context_len > UINT8_MAX)
62
0
        return C448_FAILURE;
63
64
0
    dom[0] = (uint8_t)(2 - (prehashed == 0 ? 1 : 0)
65
0
                       - (for_prehash == 0 ? 1 : 0));
66
0
    dom[1] = (uint8_t)context_len;
67
68
0
    if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
69
0
            || !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s))
70
0
            || !EVP_DigestUpdate(hashctx, dom, sizeof(dom))
71
0
            || !EVP_DigestUpdate(hashctx, context, context_len))
72
0
        return C448_FAILURE;
73
74
0
    return C448_SUCCESS;
75
0
}
76
77
/* In this file because it uses the hash */
78
c448_error_t c448_ed448_convert_private_key_to_x448(
79
                            uint8_t x[X448_PRIVATE_BYTES],
80
                            const uint8_t ed [EDDSA_448_PRIVATE_BYTES])
81
0
{
82
    /* pass the private key through oneshot_hash function */
83
    /* and keep the first X448_PRIVATE_BYTES bytes */
84
0
    return oneshot_hash(x, X448_PRIVATE_BYTES, ed,
85
0
                        EDDSA_448_PRIVATE_BYTES);
86
0
}
87
88
c448_error_t c448_ed448_derive_public_key(
89
                        uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
90
                        const uint8_t privkey[EDDSA_448_PRIVATE_BYTES])
91
12
{
92
    /* only this much used for keygen */
93
12
    uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES];
94
12
    curve448_scalar_t secret_scalar;
95
12
    unsigned int c;
96
12
    curve448_point_t p;
97
98
12
    if (!oneshot_hash(secret_scalar_ser, sizeof(secret_scalar_ser), privkey,
99
12
                      EDDSA_448_PRIVATE_BYTES))
100
0
        return C448_FAILURE;
101
102
12
    clamp(secret_scalar_ser);
103
104
12
    curve448_scalar_decode_long(secret_scalar, secret_scalar_ser,
105
12
                                sizeof(secret_scalar_ser));
106
107
    /*
108
     * Since we are going to mul_by_cofactor during encoding, divide by it
109
     * here. However, the EdDSA base point is not the same as the decaf base
110
     * point if the sigma isogeny is in use: the EdDSA base point is on
111
     * Etwist_d/(1-d) and the decaf base point is on Etwist_d, and when
112
     * converted it effectively picks up a factor of 2 from the isogenies.  So
113
     * we might start at 2 instead of 1.
114
     */
115
36
    for (c = 1; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
116
24
        curve448_scalar_halve(secret_scalar, secret_scalar);
117
118
12
    curve448_precomputed_scalarmul(p, curve448_precomputed_base, secret_scalar);
119
120
12
    curve448_point_mul_by_ratio_and_encode_like_eddsa(pubkey, p);
121
122
    /* Cleanup */
123
12
    curve448_scalar_destroy(secret_scalar);
124
12
    curve448_point_destroy(p);
125
12
    OPENSSL_cleanse(secret_scalar_ser, sizeof(secret_scalar_ser));
126
127
12
    return C448_SUCCESS;
128
12
}
129
130
c448_error_t c448_ed448_sign(
131
                        uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
132
                        const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
133
                        const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
134
                        const uint8_t *message, size_t message_len,
135
                        uint8_t prehashed, const uint8_t *context,
136
                        size_t context_len)
137
0
{
138
0
    curve448_scalar_t secret_scalar;
139
0
    EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
140
0
    c448_error_t ret = C448_FAILURE;
141
0
    curve448_scalar_t nonce_scalar;
142
0
    uint8_t nonce_point[EDDSA_448_PUBLIC_BYTES] = { 0 };
143
0
    unsigned int c;
144
0
    curve448_scalar_t challenge_scalar;
145
146
0
    if (hashctx == NULL)
147
0
        return C448_FAILURE;
148
149
0
    {
150
        /*
151
         * Schedule the secret key, First EDDSA_448_PRIVATE_BYTES is serialised
152
         * secret scalar,next EDDSA_448_PRIVATE_BYTES bytes is the seed.
153
         */
154
0
        uint8_t expanded[EDDSA_448_PRIVATE_BYTES * 2];
155
156
0
        if (!oneshot_hash(expanded, sizeof(expanded), privkey,
157
0
                          EDDSA_448_PRIVATE_BYTES))
158
0
            goto err;
159
0
        clamp(expanded);
160
0
        curve448_scalar_decode_long(secret_scalar, expanded,
161
0
                                    EDDSA_448_PRIVATE_BYTES);
162
163
        /* Hash to create the nonce */
164
0
        if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
165
0
                || !EVP_DigestUpdate(hashctx,
166
0
                                     expanded + EDDSA_448_PRIVATE_BYTES,
167
0
                                     EDDSA_448_PRIVATE_BYTES)
168
0
                || !EVP_DigestUpdate(hashctx, message, message_len)) {
169
0
            OPENSSL_cleanse(expanded, sizeof(expanded));
170
0
            goto err;
171
0
        }
172
0
        OPENSSL_cleanse(expanded, sizeof(expanded));
173
0
    }
174
175
    /* Decode the nonce */
176
0
    {
177
0
        uint8_t nonce[2 * EDDSA_448_PRIVATE_BYTES];
178
179
0
        if (!EVP_DigestFinalXOF(hashctx, nonce, sizeof(nonce)))
180
0
            goto err;
181
0
        curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce));
182
0
        OPENSSL_cleanse(nonce, sizeof(nonce));
183
0
    }
184
185
0
    {
186
        /* Scalarmul to create the nonce-point */
187
0
        curve448_scalar_t nonce_scalar_2;
188
0
        curve448_point_t p;
189
190
0
        curve448_scalar_halve(nonce_scalar_2, nonce_scalar);
191
0
        for (c = 2; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
192
0
            curve448_scalar_halve(nonce_scalar_2, nonce_scalar_2);
193
194
0
        curve448_precomputed_scalarmul(p, curve448_precomputed_base,
195
0
                                       nonce_scalar_2);
196
0
        curve448_point_mul_by_ratio_and_encode_like_eddsa(nonce_point, p);
197
0
        curve448_point_destroy(p);
198
0
        curve448_scalar_destroy(nonce_scalar_2);
199
0
    }
200
201
0
    {
202
0
        uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
203
204
        /* Compute the challenge */
205
0
        if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
206
0
                || !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point))
207
0
                || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
208
0
                || !EVP_DigestUpdate(hashctx, message, message_len)
209
0
                || !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge)))
210
0
            goto err;
211
212
0
        curve448_scalar_decode_long(challenge_scalar, challenge,
213
0
                                    sizeof(challenge));
214
0
        OPENSSL_cleanse(challenge, sizeof(challenge));
215
0
    }
216
217
0
    curve448_scalar_mul(challenge_scalar, challenge_scalar, secret_scalar);
218
0
    curve448_scalar_add(challenge_scalar, challenge_scalar, nonce_scalar);
219
220
0
    OPENSSL_cleanse(signature, EDDSA_448_SIGNATURE_BYTES);
221
0
    memcpy(signature, nonce_point, sizeof(nonce_point));
222
0
    curve448_scalar_encode(&signature[EDDSA_448_PUBLIC_BYTES],
223
0
                           challenge_scalar);
224
225
0
    curve448_scalar_destroy(secret_scalar);
226
0
    curve448_scalar_destroy(nonce_scalar);
227
0
    curve448_scalar_destroy(challenge_scalar);
228
229
0
    ret = C448_SUCCESS;
230
0
 err:
231
0
    EVP_MD_CTX_free(hashctx);
232
0
    return ret;
233
0
}
234
235
c448_error_t c448_ed448_sign_prehash(
236
                        uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
237
                        const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
238
                        const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
239
                        const uint8_t hash[64], const uint8_t *context,
240
                        size_t context_len)
241
0
{
242
0
    return c448_ed448_sign(signature, privkey, pubkey, hash, 64, 1, context,
243
0
                           context_len);
244
0
}
245
246
c448_error_t c448_ed448_verify(
247
                    const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
248
                    const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
249
                    const uint8_t *message, size_t message_len,
250
                    uint8_t prehashed, const uint8_t *context,
251
                    uint8_t context_len)
252
0
{
253
0
    curve448_point_t pk_point, r_point;
254
0
    c448_error_t error;
255
0
    curve448_scalar_t challenge_scalar;
256
0
    curve448_scalar_t response_scalar;
257
    /* Order in little endian format */
258
0
    static const uint8_t order[] = {
259
0
        0xF3, 0x44, 0x58, 0xAB, 0x92, 0xC2, 0x78, 0x23, 0x55, 0x8F, 0xC5, 0x8D,
260
0
        0x72, 0xC2, 0x6C, 0x21, 0x90, 0x36, 0xD6, 0xAE, 0x49, 0xDB, 0x4E, 0xC4,
261
0
        0xE9, 0x23, 0xCA, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
262
0
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
263
0
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00
264
0
    };
265
0
    int i;
266
267
    /*
268
     * Check that s (second 57 bytes of the sig) is less than the order. Both
269
     * s and the order are in little-endian format. This can be done in
270
     * variable time, since if this is not the case the signature if publicly
271
     * invalid.
272
     */
273
0
    for (i = EDDSA_448_PUBLIC_BYTES - 1; i >= 0; i--) {
274
0
        if (signature[i + EDDSA_448_PUBLIC_BYTES] > order[i])
275
0
            return C448_FAILURE;
276
0
        if (signature[i + EDDSA_448_PUBLIC_BYTES] < order[i])
277
0
            break;
278
0
    }
279
0
    if (i < 0)
280
0
        return C448_FAILURE;
281
282
0
    error =
283
0
        curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
284
285
0
    if (C448_SUCCESS != error)
286
0
        return error;
287
288
0
    error =
289
0
        curve448_point_decode_like_eddsa_and_mul_by_ratio(r_point, signature);
290
0
    if (C448_SUCCESS != error)
291
0
        return error;
292
293
0
    {
294
        /* Compute the challenge */
295
0
        EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
296
0
        uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
297
298
0
        if (hashctx == NULL
299
0
                || !hash_init_with_dom(hashctx, prehashed, 0, context,
300
0
                                       context_len)
301
0
                || !EVP_DigestUpdate(hashctx, signature, EDDSA_448_PUBLIC_BYTES)
302
0
                || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
303
0
                || !EVP_DigestUpdate(hashctx, message, message_len)
304
0
                || !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge))) {
305
0
            EVP_MD_CTX_free(hashctx);
306
0
            return C448_FAILURE;
307
0
        }
308
309
0
        EVP_MD_CTX_free(hashctx);
310
0
        curve448_scalar_decode_long(challenge_scalar, challenge,
311
0
                                    sizeof(challenge));
312
0
        OPENSSL_cleanse(challenge, sizeof(challenge));
313
0
    }
314
0
    curve448_scalar_sub(challenge_scalar, curve448_scalar_zero,
315
0
                        challenge_scalar);
316
317
0
    curve448_scalar_decode_long(response_scalar,
318
0
                                &signature[EDDSA_448_PUBLIC_BYTES],
319
0
                                EDDSA_448_PRIVATE_BYTES);
320
321
    /* pk_point = -c(x(P)) + (cx + k)G = kG */
322
0
    curve448_base_double_scalarmul_non_secret(pk_point,
323
0
                                              response_scalar,
324
0
                                              pk_point, challenge_scalar);
325
0
    return c448_succeed_if(curve448_point_eq(pk_point, r_point));
326
0
}
327
328
c448_error_t c448_ed448_verify_prehash(
329
                    const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
330
                    const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
331
                    const uint8_t hash[64], const uint8_t *context,
332
                    uint8_t context_len)
333
0
{
334
0
    return c448_ed448_verify(signature, pubkey, hash, 64, 1, context,
335
0
                             context_len);
336
0
}
337
338
int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
339
               const uint8_t public_key[57], const uint8_t private_key[57],
340
               const uint8_t *context, size_t context_len)
341
0
{
342
0
    return c448_ed448_sign(out_sig, private_key, public_key, message,
343
0
                           message_len, 0, context, context_len)
344
0
        == C448_SUCCESS;
345
0
}
346
347
int ED448_verify(const uint8_t *message, size_t message_len,
348
                 const uint8_t signature[114], const uint8_t public_key[57],
349
                 const uint8_t *context, size_t context_len)
350
0
{
351
0
    return c448_ed448_verify(signature, public_key, message, message_len, 0,
352
0
                             context, (uint8_t)context_len) == C448_SUCCESS;
353
0
}
354
355
int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64],
356
                 const uint8_t public_key[57], const uint8_t private_key[57],
357
                 const uint8_t *context, size_t context_len)
358
0
{
359
0
    return c448_ed448_sign_prehash(out_sig, private_key, public_key, hash,
360
0
                                   context, context_len) == C448_SUCCESS;
361
362
0
}
363
364
int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114],
365
                   const uint8_t public_key[57], const uint8_t *context,
366
                   size_t context_len)
367
0
{
368
0
    return c448_ed448_verify_prehash(signature, public_key, hash, context,
369
0
                                     (uint8_t)context_len) == C448_SUCCESS;
370
0
}
371
372
int ED448_public_from_private(uint8_t out_public_key[57],
373
                              const uint8_t private_key[57])
374
12
{
375
12
    return c448_ed448_derive_public_key(out_public_key, private_key)
376
12
        == C448_SUCCESS;
377
12
}