Coverage Report

Created: 2022-08-24 06:37

/src/cryptofuzz-sp-math/modules/wolfcrypt/ecdsa_448.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "ecdsa_448.h"
2
#include "module_internal.h"
3
#include "shared.h"
4
#include "bn_ops.h"
5
#include <cryptofuzz/util.h>
6
7
extern "C" {
8
#include <wolfssl/options.h>
9
#include <wolfssl/wolfcrypt/curve448.h>
10
#include <wolfssl/wolfcrypt/ed448.h>
11
}
12
13
namespace cryptofuzz {
14
namespace module {
15
namespace wolfCrypt_detail {
16
17
#if defined(CRYPTOFUZZ_WOLFCRYPT_ALLOCATION_FAILURES)
18
    extern bool haveAllocFailure;
19
#endif
20
21
2.14k
static bool ed448LoadPrivateKey(ed448_key& key, component::Bignum priv, Datasource& ds) {
22
2.14k
    bool ret = false;
23
24
2.14k
    CF_CHECK_EQ(wolfCrypt_bignum::Bignum::ToBin(ds, priv, key.k, sizeof(key.k)), true);
25
26
2.09k
    ret = true;
27
2.14k
end:
28
2.14k
    return ret;
29
2.09k
}
30
31
4.04k
static std::optional<std::vector<uint8_t>> ed448GetPublicKeyAsVector(ed448_key& key) {
32
4.04k
    std::optional<std::vector<uint8_t>> ret = std::nullopt;
33
4.04k
    uint8_t pub_bytes[ED448_PUB_KEY_SIZE];
34
35
4.04k
    WC_CHECK_EQ(wc_ed448_make_public(&key, pub_bytes, sizeof(pub_bytes)), MP_OKAY);
36
37
4.04k
    ret = std::vector<uint8_t>(pub_bytes, pub_bytes + sizeof(pub_bytes));
38
4.04k
end:
39
4.04k
    return ret;
40
4.04k
}
41
42
1.95k
static std::optional<component::ECC_PublicKey> ed448GetPublicKey(ed448_key& key, Datasource& ds) {
43
1.95k
    std::optional<component::ECC_PublicKey> ret = std::nullopt;
44
1.95k
    std::optional<std::vector<uint8_t>> pubv = std::nullopt;
45
1.95k
    std::optional<component::Bignum> pub = std::nullopt;
46
47
1.95k
    CF_CHECK_NE(pubv = ed448GetPublicKeyAsVector(key), std::nullopt);
48
1.95k
    CF_CHECK_NE(pub = wolfCrypt_bignum::Bignum::BinToBignum(ds, pubv->data(), pubv->size()), std::nullopt);
49
50
1.89k
    ret = {pub->ToString(), "0"};
51
52
1.95k
end:
53
1.95k
    return ret;
54
1.89k
}
55
56
2.09k
static bool ed448DerivePublicKey(ed448_key& key) {
57
2.09k
    std::optional<std::vector<uint8_t>> pubv = std::nullopt;
58
2.09k
    bool ret = false;
59
60
2.09k
    CF_CHECK_NE(pubv = ed448GetPublicKeyAsVector(key), std::nullopt);
61
2.09k
    memcpy(key.p, pubv->data(), ED448_PUB_KEY_SIZE);
62
2.09k
    key.pubKeySet = 1;
63
64
2.09k
    ret = true;
65
66
2.09k
end:
67
2.09k
    return ret;
68
2.09k
}
69
70
3.20k
static bool ed448LoadPublicKey(ed448_key& key, component::Bignum pub, Datasource& ds) {
71
3.20k
    bool ret = false;
72
73
3.20k
    CF_CHECK_EQ(wolfCrypt_bignum::Bignum::ToBin(ds, pub, key.p, sizeof(key.p)), true);
74
3.05k
    key.pubKeySet = 1;
75
76
3.05k
    ret = true;
77
3.20k
end:
78
3.20k
    return ret;
79
3.05k
}
80
81
790
std::optional<component::ECC_PublicKey> OpECC_PrivateToPublic_Curve448(operation::ECC_PrivateToPublic& op) {
82
790
    std::optional<component::ECC_PublicKey> ret = std::nullopt;
83
790
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
84
790
    wolfCrypt_detail::SetGlobalDs(&ds);
85
86
790
    static const uint8_t basepoint[CURVE448_KEY_SIZE] = {5};
87
88
790
    std::optional<std::vector<uint8_t>> priv_bytes = std::nullopt;
89
790
    uint8_t pub_bytes[CURVE448_PUB_KEY_SIZE];
90
91
    /* Load private key */
92
790
    {
93
790
        priv_bytes = util::DecToBin(op.priv.ToTrimmedString(), CURVE448_KEY_SIZE);
94
790
        CF_CHECK_NE(priv_bytes, std::nullopt);
95
96
631
        priv_bytes->data()[0] &= 0xFC;
97
631
        priv_bytes->data()[55] |= 0x80; static_assert(55 < CURVE448_KEY_SIZE);
98
631
    }
99
100
    /* Convert to public key */
101
0
    {
102
631
        CF_CHECK_EQ(curve448(pub_bytes, priv_bytes->data(), basepoint), MP_OKAY);
103
631
    }
104
105
    /* Convert public key */
106
0
    {
107
631
        ret = { util::BinToDec(pub_bytes, sizeof(pub_bytes)), "0" };
108
631
    }
109
110
790
end:
111
790
    wolfCrypt_detail::UnsetGlobalDs();
112
790
    return ret;
113
631
}
114
115
379
std::optional<component::ECC_PublicKey> OpECC_PrivateToPublic_Ed448(operation::ECC_PrivateToPublic& op) {
116
379
    std::optional<component::ECC_PublicKey> ret = std::nullopt;
117
379
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
118
379
    wolfCrypt_detail::SetGlobalDs(&ds);
119
120
379
    uint8_t pub_bytes[ED448_PUB_KEY_SIZE];
121
122
379
    ed448_key key;
123
379
    bool e448_key_inited = false;
124
125
379
    WC_CHECK_EQ(wc_ed448_init(&key), 0);
126
379
    e448_key_inited = true;
127
128
    /* Load private key */
129
379
    {
130
379
        const auto priv_bytes = util::DecToBin(op.priv.ToTrimmedString(), ED448_KEY_SIZE);
131
379
        CF_CHECK_NE(priv_bytes, std::nullopt);
132
133
249
        WC_CHECK_EQ(wc_ed448_import_private_only(priv_bytes->data(), priv_bytes->size(), &key), 0);
134
249
    }
135
136
    /* Convert to public key */
137
0
    {
138
249
        WC_CHECK_EQ(wc_ed448_make_public(&key, pub_bytes, sizeof(pub_bytes)), MP_OKAY);
139
249
    }
140
141
    /* Convert public key */
142
0
    {
143
249
        ret = { util::BinToDec(pub_bytes, sizeof(pub_bytes)), "0" };
144
249
    }
145
146
379
end:
147
379
    if ( e448_key_inited == true ) {
148
379
        wc_ed448_free(&key);
149
379
    }
150
151
379
    wolfCrypt_detail::UnsetGlobalDs();
152
379
    return ret;
153
249
}
154
155
318
std::optional<bool> OpECC_ValidatePubkey_Ed448(operation::ECC_ValidatePubkey& op) {
156
318
    std::optional<bool> ret = std::nullopt;
157
318
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
158
318
    wolfCrypt_detail::SetGlobalDs(&ds);
159
160
318
    ed448_key key;
161
318
    bool e448_key_inited = false;
162
163
318
    WC_CHECK_EQ(wc_ed448_init(&key), 0);
164
318
    e448_key_inited = true;
165
166
318
    CF_CHECK_EQ(ed448LoadPublicKey(key, op.pub.first, ds), true);
167
168
229
    haveAllocFailure = false;
169
229
    ret = wc_ed448_check_key(&key) == 0;
170
229
    if ( *ret == false && haveAllocFailure == true ) {
171
0
        ret = std::nullopt;
172
0
    }
173
174
318
end:
175
318
    if ( e448_key_inited == true ) {
176
318
        wc_ed448_free(&key);
177
318
    }
178
179
318
    wolfCrypt_detail::UnsetGlobalDs();
180
318
    return ret;
181
229
}
182
183
613
std::optional<bool> OpECC_ValidatePubkey_Curve448(operation::ECC_ValidatePubkey& op) {
184
613
    std::optional<bool> ret = std::nullopt;
185
613
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
186
613
    wolfCrypt_detail::SetGlobalDs(&ds);
187
188
613
    wolfCrypt_bignum::Bignum pub(ds);
189
613
    uint8_t pub_bytes[CURVE448_KEY_SIZE];
190
191
613
    CF_CHECK_EQ(pub.Set(op.pub.first.ToString(ds)), true);
192
563
    CF_CHECK_TRUE(pub.ToBin(pub_bytes, sizeof(pub_bytes)));
193
194
513
    haveAllocFailure = false;
195
513
    ret = wc_curve448_check_public(pub_bytes, sizeof(pub_bytes), EC448_BIG_ENDIAN) == 0;
196
513
    if ( *ret == false && haveAllocFailure == true ) {
197
0
        ret = std::nullopt;
198
0
    }
199
200
613
end:
201
202
613
    wolfCrypt_detail::UnsetGlobalDs();
203
613
    return ret;
204
513
}
205
206
2.14k
std::optional<component::ECDSA_Signature> OpECDSA_Sign_ed448(operation::ECDSA_Sign& op) {
207
2.14k
    std::optional<component::ECDSA_Signature> ret = std::nullopt;
208
2.14k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
209
2.14k
    wolfCrypt_detail::SetGlobalDs(&ds);
210
211
2.14k
    ed448_key key;
212
2.14k
    bool e448_key_inited = false;
213
2.14k
    uint8_t sig[ED448_SIG_SIZE];
214
2.14k
    word32 sigSz = sizeof(sig);
215
216
2.14k
    WC_CHECK_EQ(wc_ed448_init(&key), 0);
217
2.14k
    e448_key_inited = true;
218
219
2.14k
    CF_CHECK_EQ(wolfCrypt_detail::ed448LoadPrivateKey(key, op.priv, ds), true);
220
2.09k
    CF_CHECK_EQ(wolfCrypt_detail::ed448DerivePublicKey(key), true);
221
222
    /* Sign message */
223
2.09k
    WC_CHECK_EQ(wc_ed448_sign_msg(op.cleartext.GetPtr(), op.cleartext.GetSize(), sig, &sigSz, &key, nullptr, 0), MP_OKAY);
224
2.04k
    CF_CHECK_EQ(sigSz, ED448_SIG_SIZE);
225
2.04k
    static_assert(ED448_SIG_SIZE % 2 == 0);
226
227
2.04k
    {
228
2.04k
        std::optional<component::BignumPair> ret_sig;
229
2.04k
        std::optional<component::BignumPair> ret_pub;
230
231
2.04k
        CF_CHECK_NE(ret_sig = wolfCrypt_bignum::Bignum::BinToBignumPair(ds, sig, ED448_SIG_SIZE), std::nullopt);
232
1.95k
        CF_CHECK_NE(ret_pub = wolfCrypt_detail::ed448GetPublicKey(key, ds), std::nullopt);
233
234
1.89k
        ret = component::ECDSA_Signature(*ret_sig, *ret_pub);
235
1.89k
    }
236
237
2.14k
end:
238
2.14k
    if ( e448_key_inited == true ) {
239
2.14k
        wc_ed448_free(&key);
240
2.14k
    }
241
242
2.14k
    wolfCrypt_detail::UnsetGlobalDs();
243
2.14k
    return ret;
244
1.89k
}
245
246
2.88k
std::optional<bool> OpECDSA_Verify_ed448(operation::ECDSA_Verify& op) {
247
2.88k
    std::optional<bool> ret = std::nullopt;
248
2.88k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
249
2.88k
    wolfCrypt_detail::SetGlobalDs(&ds);
250
251
2.88k
    ed448_key key;
252
2.88k
    bool e448_key_inited = false;
253
2.88k
    uint8_t ed448sig[ED448_SIG_SIZE];
254
2.88k
    int verify;
255
2.88k
    bool oneShot = true;
256
257
2.88k
    WC_CHECK_EQ(wc_ed448_init(&key), 0);
258
2.88k
    e448_key_inited = true;
259
260
2.88k
    CF_CHECK_EQ(ed448LoadPublicKey(key, op.signature.pub.first, ds), true);
261
2.82k
    CF_CHECK_EQ(wolfCrypt_bignum::Bignum::ToBin(ds, op.signature.signature, ed448sig, sizeof(ed448sig)), true);
262
263
2.73k
#if defined(WOLFSSL_ED25519_STREAMING_VERIFY)
264
2.73k
    try { oneShot = ds.Get<bool>(); } catch ( ... ) { }
265
2.73k
#endif
266
267
2.73k
    if ( oneShot == true ) {
268
2.33k
        WC_CHECK_EQ(wc_ed448_verify_msg(ed448sig, sizeof(ed448sig), op.cleartext.GetPtr(), op.cleartext.GetSize(), &verify, &key, nullptr, 0), 0);
269
1.49k
    } else {
270
#if !defined(WOLFSSL_ED25519_STREAMING_VERIFY)
271
        CF_UNREACHABLE();
272
#else
273
407
        const auto parts = util::ToParts(ds, op.cleartext);
274
275
407
        WC_CHECK_EQ(wc_ed448_verify_msg_init(ed448sig, sizeof(ed448sig), &key, (byte)Ed448, nullptr, 0), 0);
276
277
753
        for (const auto& part : parts) {
278
753
            WC_CHECK_EQ(wc_ed448_verify_msg_update(part.first, part.second, &key), 0);
279
576
        }
280
281
407
        WC_CHECK_EQ(wc_ed448_verify_msg_final(ed448sig, sizeof(ed448sig), &verify, &key), 0);
282
301
#endif
283
301
    }
284
285
1.56k
    ret = verify ? true : false;
286
287
2.88k
end:
288
2.88k
    if ( e448_key_inited == true ) {
289
2.88k
        wc_ed448_free(&key);
290
2.88k
    }
291
292
2.88k
    wolfCrypt_detail::UnsetGlobalDs();
293
2.88k
    return ret;
294
1.56k
}
295
296
} /* namespace wolfCrypt_detail */
297
} /* namespace module */
298
} /* namespace cryptofuzz */