LibItsSecurity_externals.cc 85.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/*!
 * \file      LibItsSecurity_Functions.cc
 * \brief     Source file for Security externl functions.
 * \author    ETSI STF525
 * \copyright ETSI Copyright Notification
 *            No part may be reproduced except as authorized by written permission.
 *            The copyright and the foregoing restriction extend to reproduction in all media.
 *            All rights reserved.
 * \version   0.1
 */
11
12
#include <memory>

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "LibItsSecurity_Functions.hh"

#include "sha256.hh"
#include "sha384.hh"
#include "hmac.hh"

#include "security_ecc.hh"

#include "security_services.hh"

#include <openssl/ec.h>
#include <openssl/ecdsa.h>

#include "loggers.hh"

namespace LibItsSecurity__Functions 
{

  // FIXME Unify code with security_services
  
  /**
   * \fn OCTETSTRING fx_hashWithSha256(const OCTETSTRING& p__toBeHashedData);
35
   * \brief Produces a 256-bit (32-bytes) hash value
36
37
38
39
40
41
42
   * \param[in] p__toBeHashedData The data to be used to calculate the hash value
   * \return  The hash value
   */
  OCTETSTRING fx__hashWithSha256(
                                 const OCTETSTRING& p__toBeHashedData
                                 ) {
    loggers::get_instance().log_msg(">>> fx__hashWithSha256: p__toBeHashedData= ", p__toBeHashedData); 
43

44
    sha256 hash;
45
46
47
48
    OCTETSTRING hashData;
    hash.generate(p__toBeHashedData, hashData);
    loggers::get_instance().log_msg("fx__hashWithSha256: hashData= ", hashData);
    return hashData;
49
50
51
52
  } // End of function fx__hashWithSha256

  /**
   * \fn OCTETSTRING fx_hashWithSha384(const OCTETSTRING& p__toBeHashedData);
53
   * \brief Produces a 384-bit (48-bytes) hash value
54
55
56
57
58
59
60
   * \param[in] p__toBeHashedData Data to be used to calculate the hash value
   * \return The hash value
   */
  OCTETSTRING fx__hashWithSha384(
                                 const OCTETSTRING& p__toBeHashedData
                                 ) {
    sha384 hash;
61
62
63
64
    OCTETSTRING hashData;
    hash.generate(p__toBeHashedData, hashData);
    loggers::get_instance().log_msg("fx__hashWithSha384: hashData= ", hashData);
    return hashData;
65
66
67
68
  } // End of function fx__hashWithSha384

  /**
   * \fn OCTETSTRING fx__signWithEcdsaNistp256WithSha256(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
Yann Garcia's avatar
Yann Garcia committed
69
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on standard IEEE 1609.2
70
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
71
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
72
73
74
75
76
77
78
79
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
  OCTETSTRING fx__signWithEcdsaNistp256WithSha256(
                                                  const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                  const OCTETSTRING& p__certificateIssuer,
                                                  const OCTETSTRING& p__privateKey
                                                  ) {
garciay's avatar
garciay committed
80
81
82
83
    loggers::get_instance().log_msg(">>> fx__signWithEcdsaNistp256WithSha256: data=", p__toBeSignedSecuredMessage); 
    loggers::get_instance().log_msg(">>> fx__signWithEcdsaNistp256WithSha256: issuer=", p__certificateIssuer); 
    loggers::get_instance().log_msg(">>> fx__signWithEcdsaNistp256WithSha256: private key=", p__privateKey); 
    
84
    // Sanity checks
85
    if ((p__certificateIssuer.lengthof() != 32) || (p__privateKey.lengthof() != 32)) {
86
      loggers::get_instance().log("fx__signWithEcdsaNistp256WithSha256: Wrong parameters");
87
      return OCTETSTRING(0, nullptr);
88
89
90
91
    }
    
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
92
93
94
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeSignedSecuredMessage, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
95
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
96
      hashData2 = p__certificateIssuer;
97
98
    } else {
      hashData2 = hash.get_sha256_empty_string(); // Hash of empty string
99
    }
100
101
102
103
104
    loggers::get_instance().log_msg("fx__signWithEcdsaNistp256WithSha256: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__signWithEcdsaNistp256WithSha256: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    loggers::get_instance().log_msg("fx__signWithEcdsaNistp256WithSha256: Hash (Data input) || Hash (Signer identifier input)=", hashData1);
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
105
    hash.generate(hashData1, hashData);
106
    loggers::get_instance().log_msg("fx__signWithEcdsaNistp256WithSha256: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
107
    // Calculate the signature
108
109
110
    security_ecc k(ec_elliptic_curves::nist_p_256, p__privateKey);
    OCTETSTRING r_sig;
    OCTETSTRING s_sig;
111
    if (k.sign(hashData, r_sig, s_sig) == 0) {
112
113
114
115
      OCTETSTRING os = r_sig + s_sig;
      loggers::get_instance().log_msg("r_sig= ", r_sig);
      loggers::get_instance().log_msg("s_sig= ", s_sig);
      loggers::get_instance().log_msg("sig= ", os);
116
117
118
      return os;
    }

119
    return OCTETSTRING(0, nullptr);
120
121
  }

Yann Garcia's avatar
Yann Garcia committed
122
123
124
125
126
127
128
  /**
   * \fn OCTETSTRING fx__signWithEcdsaNistp256WithSha256(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on raw data
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
Yann Garcia's avatar
Yann Garcia committed
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  OCTETSTRING fx__test__signWithEcdsaNistp256WithSha256(
                                                        const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                        const OCTETSTRING& p__privateKey
                                                        ) {
    loggers::get_instance().log_msg(">>> fx__test__signWithEcdsaNistp256WithSha256: data=", p__toBeSignedSecuredMessage); 
    loggers::get_instance().log_msg(">>> fx__test__signWithEcdsaNistp256WithSha256: private key=", p__privateKey); 
    
    // Sanity checks
    if (p__privateKey.lengthof() != 32) {
      loggers::get_instance().log("fx__test__signWithEcdsaNistp256WithSha256: Wrong parameters");
      return OCTETSTRING(0, nullptr);
    }
    
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeSignedSecuredMessage, hashData1);
    loggers::get_instance().log_msg("fx__test__signWithEcdsaNistp256WithSha256: Hash (Data input)=", hashData1);
    // Calculate the signature
    security_ecc k(ec_elliptic_curves::nist_p_256, p__privateKey);
    OCTETSTRING r_sig;
    OCTETSTRING s_sig;
    if (k.sign(hashData1, r_sig, s_sig) == 0) {
      OCTETSTRING os = r_sig + s_sig;
      loggers::get_instance().log_msg("r_sig= ", r_sig);
      loggers::get_instance().log_msg("s_sig= ", s_sig);
      loggers::get_instance().log_msg("sig= ", os);
      return os;
    }

    return OCTETSTRING(0, nullptr);
  }

162
163
  /**
   * \fn OCTETSTRING fx__signWithEcdsaBrainpoolp256WithSha256(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
Yann Garcia's avatar
Yann Garcia committed
164
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on standard IEEE 1609.2
165
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
166
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
167
168
169
170
171
172
173
174
175
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
  OCTETSTRING fx__signWithEcdsaBrainpoolp256WithSha256(
                                                       const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                       const OCTETSTRING& p__certificateIssuer,
                                                       const OCTETSTRING& p__privateKey
                                                       ) {
    // Sanity checks
176
    if ((p__certificateIssuer.lengthof() != 32) || (p__privateKey.lengthof() != 32)) {
177
      loggers::get_instance().log("fx__signWithEcdsaBrainpoolp256WithSha256: Wrong parameters");
178
      return OCTETSTRING(0, nullptr);
179
180
181
182
    }
    
    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
183
184
185
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeSignedSecuredMessage, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
186
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
187
      hashData2 = p__certificateIssuer;
188
189
    } else {
      hashData2 = hash.get_sha256_empty_string(); // Hash of empty string
190
    }
191
192
193
194
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp256WithSha256: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp256WithSha256: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
195
    hash.generate(hashData1, hashData);
196
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp256WithSha256: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
197
    // Calculate the signature
198
199
200
    security_ecc k(ec_elliptic_curves::brainpool_p_256_r1, p__privateKey);
    OCTETSTRING r_sig;
    OCTETSTRING s_sig;
201
    if (k.sign(hashData, r_sig, s_sig) == 0) {
202
203
204
205
      OCTETSTRING os = r_sig + s_sig;
      loggers::get_instance().log_msg("r_sig= ", r_sig);
      loggers::get_instance().log_msg("s_sig= ", s_sig);
      loggers::get_instance().log_msg("sig= ", os);
206
207
208
      return os;
    }

209
    return OCTETSTRING(0, nullptr);
210
211
212
213
  }

  /**
   * \fn OCTETSTRING fx__signWithEcdsaBrainpoolp384WithSha384(const OCTETSTRING& p__toBeSignedSecuredMessage, const OCTETSTRING& p__privateKey);
Yann Garcia's avatar
Yann Garcia committed
214
   * \brief Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on standard IEEE 1609.2
215
   * \param[in] p__toBeSignedSecuredMessage The data to be signed
216
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
217
218
219
220
221
222
223
224
225
   * \param[in] p__privateKey The private key
   * \return The signature value
   */
  OCTETSTRING fx__signWithEcdsaBrainpoolp384WithSha384(
                                                       const OCTETSTRING& p__toBeSignedSecuredMessage,
                                                       const OCTETSTRING& p__certificateIssuer,
                                                       const OCTETSTRING& p__privateKey
                                                       ) {
    // Sanity checks
226
	    if ((p__certificateIssuer.lengthof() != 48) || (p__privateKey.lengthof() != 48)) {
227
      loggers::get_instance().log("fx__signWithEcdsaBrainpoolp384WithSha384: Wrong parameters");
228
      return OCTETSTRING(0, nullptr);
229
230
231
232
    }
    
    // Calculate the SHA384 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha384 hash;
233
234
235
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeSignedSecuredMessage, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
236
    if (p__certificateIssuer != int2oct(0, 48)) { // || Hash (Signer identifier input)
237
      hashData2 = p__certificateIssuer;
238
239
    } else {
      hashData2 = hash.get_sha384_empty_string(); // Hash of empty string
240
    }
241
242
243
244
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp384WithSha384: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp384WithSha384: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
245
    hash.generate(hashData1, hashData);
246
    loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp384WithSha384: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
247
    // Calculate the signature
248
249
250
    security_ecc k(ec_elliptic_curves::brainpool_p_384_r1, p__privateKey);
    OCTETSTRING r_sig;
    OCTETSTRING s_sig;
251
    if (k.sign(hashData, r_sig, s_sig) == 0) {
252
253
254
255
      OCTETSTRING os = r_sig + s_sig;
      loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp384WithSha384: r_sig= ", r_sig);
      loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp384WithSha384: s_sig= ", s_sig);
      loggers::get_instance().log_msg("fx__signWithEcdsaBrainpoolp384WithSha384: sig= ", os);
256
257
258
      return os;
    }

259
    return OCTETSTRING(0, nullptr);
260
261
262
263
  }

  /**
   * \fn BOOLEAN fx__verifyWithEcdsaNistp256WithSha256(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaNistp256PublicKeyCompressed);
Yann Garcia's avatar
Yann Garcia committed
264
   * \brief Verify the signature of the specified data based on standard IEEE 1609.2
265
   * \param[in] p__toBeVerifiedData The data to be verified
266
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
267
268
269
270
271
272
273
274
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaNistp256PublicKeyCompressed The compressed public key (x coordinate only)
   * \return true on success, false otherwise
   */
  BOOLEAN fx__verifyWithEcdsaNistp256WithSha256(
                                                const OCTETSTRING& p__toBeVerifiedData,
                                                const OCTETSTRING& p__certificateIssuer,
                                                const OCTETSTRING& p__signature,
275
                                                const OCTETSTRING& p__ecdsaNistp256PublicKeyCompressed,
276
                                                const INTEGER& p__compressedMode
277
                                                ) {
278
    // Sanity checks
279
    if ((p__certificateIssuer.lengthof() != 32) || (p__signature.lengthof() != 64) || (p__ecdsaNistp256PublicKeyCompressed.lengthof() != 32)) {
280
281
282
283
284
285
      loggers::get_instance().log("fx__verifyWithEcdsaNistp256WithSha256: Wrong parameters");
      return FALSE;
    }

    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
286
287
288
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeVerifiedData, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
289
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
290
      hashData2 = p__certificateIssuer;
291
292
    } else {
      hashData2 = hash.get_sha256_empty_string(); // Hash of empty string
293
    }
294
295
296
297
    loggers::get_instance().log_msg("fx__verifyWithEcdsaNistp256WithSha256: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__verifyWithEcdsaNistp256WithSha256: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
298
    hash.generate(hashData1, hashData);
299
    loggers::get_instance().log_msg("fx__verifyWithEcdsaNistp256WithSha256: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
300
    // Check the signature
301
302
    security_ecc k(ec_elliptic_curves::nist_p_256, p__ecdsaNistp256PublicKeyCompressed, (p__compressedMode == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    if (k.sign_verif(hashData, p__signature) == 0) {
303
304
305
306
307
308
      return TRUE;
    }

    return FALSE;
  }
  
Yann Garcia's avatar
Yann Garcia committed
309
310
311
312
313
314
315
316
  /**
   * \fn BOOLEAN fx__verifyWithEcdsaNistp256WithSha256(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__ecdsaNistp256PublicKeyCompressed);
   * \brief Verify the signature of the specified data based on raw data
   * \param[in] p__toBeVerifiedData The data to be verified
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaNistp256PublicKeyCompressed The compressed public key (x coordinate only)
   * \return true on success, false otherwise
   */
Yann Garcia's avatar
Yann Garcia committed
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
  BOOLEAN fx__test__verifyWithEcdsaNistp256WithSha256(
                                                      const OCTETSTRING& p__toBeVerifiedData,
                                                      const OCTETSTRING& p__signature,
                                                      const OCTETSTRING& p__ecdsaNistp256PublicKeyCompressed,
                                                      const INTEGER& p__compressedMode
                                                      ) {
    // Sanity checks
    if ((p__signature.lengthof() != 64) || (p__ecdsaNistp256PublicKeyCompressed.lengthof() != 32)) {
      loggers::get_instance().log("fx__test__verifyWithEcdsaNistp256WithSha256: Wrong parameters");
      return FALSE;
    }

    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeVerifiedData, hashData1);
    loggers::get_instance().log_msg("fx__test__verifyWithEcdsaNistp256WithSha256: Hash (Data input)=", hashData1);
    // Check the signature
    security_ecc k(ec_elliptic_curves::nist_p_256, p__ecdsaNistp256PublicKeyCompressed, (p__compressedMode == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    if (k.sign_verif(hashData1, p__signature) == 0) {
      return TRUE;
    }

    return FALSE;
  }
  
343
344
  /**
   * \fn BOOLEAN fx__verifyWithEcdsaNistp256WithSha256_1(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaNistp256PublicKeyX, const OCTETSTRING& p__ecdsaNistp256PublicKeyY);
Yann Garcia's avatar
Yann Garcia committed
345
   * \brief Verify the signature of the specified data based on standard IEEE 1609.2
346
   * \param[in] p__toBeVerifiedData The data to be verified
347
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
348
349
350
351
352
353
354
355
356
357
358
359
360
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaNistp256PublicKeyX The public key (x coordinate)
   * \param[in] p__ecdsaNistp256PublicKeyY The public key (y coordinate)
   * \return true on success, false otherwise
   */
  BOOLEAN fx__verifyWithEcdsaNistp256WithSha256__1(
                                                   const OCTETSTRING& p__toBeVerifiedData,
                                                   const OCTETSTRING& p__certificateIssuer,
                                                   const OCTETSTRING& p__signature,
                                                   const OCTETSTRING& p__ecdsaNistp256PublicKeyX,
                                                   const OCTETSTRING& p__ecdsaNistp256PublicKeyY
                                                   ) {
    // Sanity checks
Yann Garcia's avatar
Yann Garcia committed
361
    if ((p__certificateIssuer.lengthof() != 32) || (p__signature.lengthof() != 64) || (p__ecdsaNistp256PublicKeyX.lengthof() != 32) || (p__ecdsaNistp256PublicKeyY.lengthof() != 32)) {
362
363
364
365
366
367
      loggers::get_instance().log("fx__verifyWithEcdsaNistp256WithSha256__1: Wrong parameters");
      return FALSE;
    }

    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
368
369
370
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeVerifiedData, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
371
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
372
      hashData2 = p__certificateIssuer;
373
374
    } else {
      hashData2 = hash.get_sha256_empty_string(); // Hash of empty string
375
    }
376
377
378
379
    loggers::get_instance().log_msg("fx__verifyWithEcdsaNistp256WithSha256__1: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__verifyWithEcdsaNistp256WithSha256__1: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
380
    hash.generate(hashData1, hashData);
381
    loggers::get_instance().log_msg("fx__verifyWithEcdsaNistp256WithSha256__1: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
382
    // Check the signature
383
    security_ecc k(ec_elliptic_curves::nist_p_256, p__ecdsaNistp256PublicKeyX, p__ecdsaNistp256PublicKeyY);
384
    //security_ecc k(ec_elliptic_curves::nist_p_256);
385
    if (k.sign_verif(hashData, p__signature) == 0) {
386
387
388
389
390
391
392
393
      return TRUE;
    }

    return FALSE;
  }

  /**
   * \fn BOOLEAN fx__verifyWithEcdsaBrainpoolp256WithSha256(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyCompressed);
Yann Garcia's avatar
Yann Garcia committed
394
   * \brief Verify the signature of the specified data based on standard IEEE 1609.2
395
   * \param[in] p__toBeVerifiedData The data to be verified
396
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
397
398
399
400
401
402
403
404
405
406
407
408
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaBrainpoolp256PublicKeyCompressed The compressed public key (x coordinate only)
   * \return true on success, false otherwise
   */
  BOOLEAN fx__verifyWithEcdsaBrainpoolp256WithSha256(
                                                     const OCTETSTRING& p__toBeVerifiedData,
                                                     const OCTETSTRING& p__certificateIssuer,
                                                     const OCTETSTRING& p__signature,
                                                     const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyCompressed,
                                                     const INTEGER& p__compressedMode
                                                     ) {
    // Sanity checks
409
    if ((p__certificateIssuer.lengthof() != 32) || (p__signature.lengthof() != 64) || (p__ecdsaBrainpoolp256PublicKeyCompressed.lengthof() != 32)) {
410
411
412
413
414
415
      loggers::get_instance().log("fx__verifyWithEcdsaBrainpoolp256WithSha256: Wrong parameters");
      return FALSE;
    }

    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
416
417
418
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeVerifiedData, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
419
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
420
      hashData2 = p__certificateIssuer;
421
422
    } else {
      hashData2 = hash.get_sha256_empty_string(); // Hash of empty string
423
    }
424
425
426
427
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp256WithSha256: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp256WithSha256: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
428
    hash.generate(hashData1, hashData);
429
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp256WithSha256: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
430
    // Check the signature
431
432
    security_ecc k(ec_elliptic_curves::brainpool_p_256_r1, p__ecdsaBrainpoolp256PublicKeyCompressed, (p__compressedMode == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    if (k.sign_verif(hashData, p__signature) == 0) {
433
434
435
436
437
438
439
440
      return TRUE;
    }

    return FALSE;
  }

  /**
   * \fn BOOLEAN fx__verifyWithEcdsaBrainpoolp256WithSha256_1(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyX, const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyY);
Yann Garcia's avatar
Yann Garcia committed
441
   * \brief Verify the signature of the specified data based on standard IEEE 1609.2
442
   * \param[in] p__toBeVerifiedData The data to be verified
443
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
444
445
446
447
448
449
450
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaBrainpoolp256PublicKeyX The public key (x coordinate)
   * \param[in] p__ecdsaBrainpoolp256PublicKeyY The public key (y coordinate)
   * \return true on success, false otherwise
   */
  BOOLEAN fx__verifyWithEcdsaBrainpoolp256WithSha256__1(
                                                        const OCTETSTRING& p__toBeVerifiedData,
451
                                                        const OCTETSTRING& p__certificateIssuer,
452
453
454
455
456
                                                        const OCTETSTRING& p__signature,
                                                        const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyX,
                                                        const OCTETSTRING& p__ecdsaBrainpoolp256PublicKeyY
                                                        ) {
    // Sanity checks
Yann Garcia's avatar
Yann Garcia committed
457
    if ((p__certificateIssuer.lengthof() != 32) || (p__signature.lengthof() != 64) || (p__ecdsaBrainpoolp256PublicKeyX.lengthof() != 32) || (p__ecdsaBrainpoolp256PublicKeyY.lengthof() != 32)) {
458
459
460
461
462
463
      loggers::get_instance().log("fx__verifyWithEcdsaBrainpoolp256WithSha256__1: Wrong parameters");
      return FALSE;
    }

    // Calculate the SHA256 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha256 hash;
464
465
466
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeVerifiedData, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
467
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
468
      hashData2 = p__certificateIssuer;
469
470
    } else {
      hashData2 = hash.get_sha256_empty_string(); // Hash of empty string
471
    }
472
473
474
475
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp256WithSha256__1: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp256WithSha256__1: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
476
    hash.generate(hashData1, hashData);
477
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp256WithSha256__1: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
478
    // Check the signature
479
480
    security_ecc k(ec_elliptic_curves::brainpool_p_256_r1, p__ecdsaBrainpoolp256PublicKeyX, p__ecdsaBrainpoolp256PublicKeyY);
    if (k.sign_verif(hashData, p__signature) == 0) {
481
482
483
484
485
486
487
488
      return TRUE;
    }

    return FALSE;
  }

  /**
   * \fn BOOLEAN fx__verifyWithEcdsaBrainpoolp384WithSha384(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyCompressed);
Yann Garcia's avatar
Yann Garcia committed
489
   * \brief Verify the signature of the specified data based on standard IEEE 1609.2
490
   * \param[in] p__toBeVerifiedData The data to be verified
491
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
492
493
494
495
496
497
498
499
500
501
502
503
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaBrainpoolp384PublicKeyCompressed The compressed public key (x coordinate only)
   * \return true on success, false otherwise
   */
  BOOLEAN fx__verifyWithEcdsaBrainpoolp384WithSha384(
                                                     const OCTETSTRING& p__toBeVerifiedData,
                                                     const OCTETSTRING& p__certificateIssuer,
                                                     const OCTETSTRING& p__signature,
                                                     const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyCompressed,
                                                     const INTEGER& p__compressedMode
                                                     ) {
    // Sanity checks
504
    if ((p__certificateIssuer.lengthof() != 48) || (p__signature.lengthof() != 96) || (p__ecdsaBrainpoolp384PublicKeyCompressed.lengthof() != 48)) {
505
506
507
508
509
510
      loggers::get_instance().log("fx__verifyWithEcdsaBrainpoolp384WithSha384: Wrong parameters");
      return FALSE;
    }

    // Calculate the SHA384 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha384 hash;
511
512
513
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeVerifiedData, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
514
    if (p__certificateIssuer != int2oct(0, 48)) { // || Hash (Signer identifier input)
515
      hashData2 = p__certificateIssuer;
516
517
    } else {
      hashData2 = hash.get_sha384_empty_string(); // Hash of empty string
518
    }
519
520
521
522
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp384WithSha384: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp384WithSha384: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
523
    hash.generate(hashData1, hashData);
524
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp384WithSha384: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
525
    // Check the signature
526
527
    security_ecc k(ec_elliptic_curves::brainpool_p_384_r1, p__ecdsaBrainpoolp384PublicKeyCompressed, (p__compressedMode == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
    if (k.sign_verif(hashData, p__signature) == 0) {
528
529
530
531
532
533
534
535
      return TRUE;
    }

    return FALSE;
  }

  /**
   * \fn BOOLEAN fx__verifyWithEcdsaBrainpoolp384WithSha384_1(const OCTETSTRING& p__toBeVerifiedData, const OCTETSTRING& p__signature, const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyX, const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyY);
Yann Garcia's avatar
Yann Garcia committed
536
   * \brief Verify the signature of the specified data based on standard IEEE 1609.2
537
   * \param[in] p__toBeVerifiedData The data to be verified
538
   * \param[in] p__certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
539
540
541
542
543
544
545
   * \param[in] p__signature The signature
   * \param[in] p__ecdsaBrainpoolp384PublicKeyX The public key (x coordinate)
   * \param[in] p__ecdsaBrainpoolp384PublicKeyY The public key (y coordinate)
   * \return true on success, false otherwise
   */
  BOOLEAN fx__verifyWithEcdsaBrainpoolp384WithSha384__1(
                                                        const OCTETSTRING& p__toBeVerifiedData,
546
                                                        const OCTETSTRING& p__certificateIssuer,
547
548
549
550
551
                                                        const OCTETSTRING& p__signature,
                                                        const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyX,
                                                        const OCTETSTRING& p__ecdsaBrainpoolp384PublicKeyY
                                                        ) {
    // Sanity checks
Yann Garcia's avatar
Yann Garcia committed
552
    if ((p__certificateIssuer.lengthof() != 48) || (p__signature.lengthof() != 96) || (p__ecdsaBrainpoolp384PublicKeyX.lengthof() != 48) || (p__ecdsaBrainpoolp384PublicKeyY.lengthof() != 48)) {
553
554
555
556
557
558
      loggers::get_instance().log("fx__verifyWithEcdsaBrainpoolp384WithSha384__1: Wrong parameters");
      return FALSE;
    }

    // Calculate the SHA384 of the hashed data for signing: Hash ( Hash (Data input) || Hash (Signer identifier input) )
    sha384 hash;
559
560
561
    OCTETSTRING hashData1; // Hash (Data input)
    hash.generate(p__toBeVerifiedData, hashData1);
    OCTETSTRING hashData2; // Hash (Signer identifier input)
562
    if (p__certificateIssuer != int2oct(0, 32)) { // || Hash (Signer identifier input)
563
      hashData2 = p__certificateIssuer;
564
565
    } else {
      hashData2 = hash.get_sha384_empty_string(); // Hash of empty string
566
    }
567
568
569
570
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp384WithSha384: Hash (Data input)=", hashData1);
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp384WithSha384: Hash (Signer identifier input)=", hashData2);
    hashData1 += hashData2; // Hash (Data input) || Hash (Signer identifier input)
    OCTETSTRING hashData; // Hash ( Hash (Data input) || Hash (Signer identifier input) )
571
    hash.generate(hashData1, hashData);
572
    loggers::get_instance().log_msg("fx__verifyWithEcdsaBrainpoolp384WithSha384: Hash ( Hash (Data input) || Hash (Signer identifier input) )=", hashData);
573
    // Check the signature
574
575
    security_ecc k(ec_elliptic_curves::brainpool_p_384_r1, p__ecdsaBrainpoolp384PublicKeyX, p__ecdsaBrainpoolp384PublicKeyY);
    if (k.sign_verif(hashData, p__signature) == 0) {
576
577
578
579
580
581
582
      return TRUE;
    }

    return FALSE;
  }

  /**
Yann Garcia's avatar
Yann Garcia committed
583
   * \fn OCTETSTRING fx__hmac__sha256(const OCTETSTRING& p__k, const OCTETSTRING& p__m);
584
585
586
587
588
   * \brief Generate a HMAC-SHA256 value based on the provided secret key
   * \param[in] p__k The secret key used for the HMAC calculation
   * \param[in] p__m The message
   * \return The HMAC value resized to 16-byte
   */
Yann Garcia's avatar
Yann Garcia committed
589
590
  OCTETSTRING fx__hmac__sha256(const OCTETSTRING& p__k, const OCTETSTRING& p__m) {
    loggers::get_instance().log(">>> fx__hmac__sha256");
591
592

    hmac h(hash_algorithms::sha_256); // TODO Use ec_encryption_algorithm
593
594
    OCTETSTRING t;
    if (h.generate(p__m, p__k, t) == -1) {
Yann Garcia's avatar
Yann Garcia committed
595
      loggers::get_instance().warning("fx__hmac__sha256: Failed to generate HMAC");
596
      return OCTETSTRING(0, nullptr);
597
    }
Yann Garcia's avatar
Yann Garcia committed
598
    loggers::get_instance().log_msg("fx__hmac__sha256: HMAC: ", t);
599

600
    return t;
601
602
603
  }

  /**
Yann Garcia's avatar
Yann Garcia committed
604
   * \fn OCTETSTRING fx__encrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__pt);
605
606
607
608
609
610
   * \brief Encrypt the message using AES 128 CCM algorithm
   * \param[in] p__k The symmetric encryption key
   * \param[in] p__n The initial vector, nonce vector
   * \param[in] p__pt The message to encrypt
   * \return The encrypted message concatenated to the AES 128 CCM tag
   */
Yann Garcia's avatar
Yann Garcia committed
611
612
  OCTETSTRING fx__encrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__pt) {
    loggers::get_instance().log(">>> fx__encrypt__aes__128__ccm__test");
613
614
    
    security_ecc ec(ec_elliptic_curves::nist_p_256);
615
616
    OCTETSTRING enc_message;
    if (ec.encrypt(encryption_algotithm::aes_128_ccm, p__k, p__n, p__pt, enc_message) == -1) {
Yann Garcia's avatar
Yann Garcia committed
617
      loggers::get_instance().warning("fx__encrypt__aes__128__ccm__test: Failed to encrypt message");
618
      return OCTETSTRING(0, nullptr);
619
    }
620
    OCTETSTRING os(enc_message + ec.tag());
Yann Garcia's avatar
Yann Garcia committed
621
    loggers::get_instance().log_msg("fx__encrypt__aes__128__ccm__test: encrypted message: ", os);
622
623
624
625

    return os;
  }
  
Yann Garcia's avatar
Yann Garcia committed
626
627
628
629
630
631
632
633
634
635
  /**
   * \fn OCTETSTRING fx__encrypt__aes__128__gcm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__pt);
   * \brief Encrypt the message using AES 128 GCM algorithm
   * \param[in] p__k The symmetric encryption key
   * \param[in] p__n The initial vector, nonce vector
   * \param[in] p__pt The message to encrypt
   * \return The encrypted message concatenated to the AES 128 CCM tag
   */
  OCTETSTRING fx__encrypt__aes__128__gcm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__pt) {
    loggers::get_instance().log(">>> fx__encrypt__aes__128__gcm__test");
636
637
638
639
    
    security_ecc ec(ec_elliptic_curves::nist_p_256);
    OCTETSTRING enc_message;
    if (ec.encrypt(encryption_algotithm::aes_128_gcm, p__k, p__n, p__pt, enc_message) == -1) {
Yann Garcia's avatar
Yann Garcia committed
640
      loggers::get_instance().warning("fx__encrypt__aes__128__gcm__test: Failed to encrypt message");
641
642
643
      return OCTETSTRING(0, nullptr);
    }
    OCTETSTRING os(enc_message + ec.tag());
Yann Garcia's avatar
Yann Garcia committed
644
    loggers::get_instance().log_msg("fx__encrypt__aes__128__gcm__test: encrypted message: ", os);
645
646
647
648

    return os;
  }
  
649
  /**
Yann Garcia's avatar
Yann Garcia committed
650
   * \fn OCTETSTRING fx__decrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__ct);
651
652
653
654
655
656
   * \brief Encrypt the message using AES 128 CCM algorithm
   * \param[in] p__k The symmetric encryption key
   * \param[in] p__n The initial vector, nonce vector
   * \param[in] p__ct The encrypted message concatenated to the AES 128 CCM tag
   * \return The original message
   */
Yann Garcia's avatar
Yann Garcia committed
657
658
659
660
  OCTETSTRING fx__decrypt__aes__128__ccm__test(const OCTETSTRING& p__k, const OCTETSTRING& p__n, const OCTETSTRING& p__ct) {
    loggers::get_instance().log_msg(">>> fx__decrypt__aes__128__ccm__test: p__k: ", p__k);
    loggers::get_instance().log_msg(">>> fx__decrypt__aes__128__ccm__test: p__n: ", p__n);
    loggers::get_instance().log_msg(">>> fx__decrypt__aes__128__ccm__test: p__ct: ", p__ct);
661
662
663
    
    security_ecc ec(ec_elliptic_curves::nist_p_256);
    // Extract the tag
664
    OCTETSTRING tag(16, p__ct.lengthof() - 16 + static_cast<const unsigned char*>(p__ct));
Yann Garcia's avatar
Yann Garcia committed
665
    loggers::get_instance().log_msg("fx__decrypt__aes__128__ccm__test: tag: ", tag);
666
    // Remove the tag from the end of the encrypted message
667
    OCTETSTRING ct(p__ct.lengthof() - 16, static_cast<const unsigned char*>(p__ct));
Yann Garcia's avatar
Yann Garcia committed
668
    loggers::get_instance().log_msg("fx__decrypt__aes__128__ccm__test: ct: ", ct);
669
    
670
    OCTETSTRING message;
671
    if (ec.decrypt(encryption_algotithm::aes_128_ccm, p__k, p__n, tag, ct, message) == -1) {
Yann Garcia's avatar
Yann Garcia committed
672
      loggers::get_instance().warning("fx__decrypt__aes__128__ccm__test: Failed to decrypt message");
673
      return OCTETSTRING(0, nullptr);
674
    }
Yann Garcia's avatar
Yann Garcia committed
675
    loggers::get_instance().log_to_hexa("fx__decrypt__aes__128__ccm__test: decrypted message: ", message);
676
    
677
    return message;
678
679
680
681
682
683
684
685
686
687
688
689
690
  }
  
  /**
   * \fn OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__recipientsPublicKeyX, const OCTETSTRING& p__recipientsPublicKeyY, OCTETSTRING& p__publicEphemeralKeyX, OCTETSTRING& p__publicEphemeralKeyY, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce);
   * \brief Encrypt the message using ECIES algorithm to encrypt AES 128 CCM symmetric key, as defined in IEEE Std 1609.2-2017
   * \param[in] p__toBeEncryptedSecuredMessage The message to be encrypted
   * \param[in] p__recipientsPublicKeyCompressed The Recipient's compressed public key
   * \param[in] p__compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
   * \param[out] p__publicEphemeralKeyCompressed The public ephemeral compressed key
   * \param[out] p__ephemeralCompressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
   * \param[out] p__encrypted__sym__key The encrypted AES 128 symmetric key
   * \param[out] p__authentication__vector The tag of the encrypted AES 128 symmetric key
   * \param[out] p__nonce The nonce vector
691
   * \param[in] p__use__hardcoded__values In debug mode, set to true to use hardcoded values
692
693
694
695
696
697
   * \return The original message
   * \see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
   * \see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
   * \see http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf
   */
  // TODO Use common function for both fx__encryptWithEciesxxx and fx__decryptWithEciesxxx function
698
  OCTETSTRING fx__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__recipientsPublicKeyCompressed, const INTEGER& p__compressedMode, const OCTETSTRING& p__salt, OCTETSTRING& p__publicEphemeralKeyCompressed, INTEGER& p__ephemeralCompressedMode,OCTETSTRING& p__aes__sym__key, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce, const BOOLEAN& p__use__hardcoded__values) {
699
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__toBeEncryptedSecuredMessage);
700
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__recipientsPublicKeyCompressed: ", p__recipientsPublicKeyCompressed);
701
    loggers::get_instance().log(">>> fx__encryptWithEciesNistp256WithSha256: p__compressedMode: %d", static_cast<int>(p__compressedMode));
702
703
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesNistp256WithSha256: p__salt: ", p__salt);
    loggers::get_instance().log(">>> fx__encryptWithEciesNistp256WithSha256: p__use__hardcoded__values: %x", static_cast<const boolean>(p__use__hardcoded__values));
704
    
705
706
    // 1. Generate new Private/Public Ephemeral key
    std::unique_ptr<security_ecc> ec;
707
    if (!static_cast<const boolean>(p__use__hardcoded__values)) {
708
709
710
711
712
713
      ec.reset(new security_ecc(ec_elliptic_curves::nist_p_256));
      if (ec->generate() == -1) {
        loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate ephemeral keys");
        return OCTETSTRING(0, nullptr);
      }
    } else {
714
      ec.reset(new security_ecc(ec_elliptic_curves::nist_p_256, str2oct("0722B39ABC7B6C5301CA0408F454F81553D7FE59F492DBF385B6B6D1F81E0F68"))); // Hardcoded private key
715
    }
716
    // 2. Generate and derive shared secret based on recipient's private keys
717
    security_ecc ec_comp(ec_elliptic_curves::nist_p_256, p__recipientsPublicKeyCompressed, (static_cast<int>(p__compressedMode) == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
718
719
    if (static_cast<const boolean>(p__use__hardcoded__values)) { // Set AES encryption key to an harcoded value
      ec->symmetric_encryption_key(str2oct("5A4E63B247C714644E85CAC49BD26C81"));
720
721
    }
    if (ec->generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y(), p__salt) == -1) {
722
      loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to generate and derive secret key");
723
      return OCTETSTRING(0, nullptr);
724
    }
725
726
727
728
729
    
    // Set the AES symmetric key
    loggers::get_instance().log_msg("fx__encryptWithEciesNistp256WithSha256: AES symmetric key: ", ec->symmetric_encryption_key());
    p__aes__sym__key = ec->symmetric_encryption_key();
    loggers::get_instance().log_msg("fx__encryptWithEciesNistp256WithSha256: p__aes__sym__key: ", p__aes__sym__key);
730
    // Set the encrypted symmetric key
731
732
    loggers::get_instance().log_msg("fx__encryptWithEciesNistp256WithSha256: Encrypted symmetric key: ", ec->encrypted_symmetric_key());
    p__encrypted__sym__key = ec->encrypted_symmetric_key();
733
    loggers::get_instance().log_msg("fx__encryptWithEciesNistp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
734
    // Set the tag of the symmetric key encryption
735
    p__authentication__vector = ec->tag();
736
    loggers::get_instance().log_msg("fx__encryptWithEciesNistp256WithSha256: p__authentication__vector: ", p__authentication__vector);
737
    // Set ephemeral public keys
738
739
740
741
    p__publicEphemeralKeyCompressed = ec->public_key_compressed();
    loggers::get_instance().log_msg("fx__encryptWithEciesNistp256WithSha256: Ephemeral public compressed key: ", p__publicEphemeralKeyCompressed);
    p__ephemeralCompressedMode = (ec->public_key_compressed_mode() == ecc_compressed_mode::compressed_y_0) ? 0 : 1;
    loggers::get_instance().log("fx__encryptWithEciesNistp256WithSha256: Ephemeral public compressed mode: %d: ", p__ephemeralCompressedMode);
742
    // 3. Retrieve AES 128 parameters
743
    p__nonce = ec->nonce();
744
    loggers::get_instance().log_msg("fx__encryptWithEciesNistp256WithSha256: p__nonce: ", p__nonce);
745
    // 4. Encrypt the data using AES-128 CCM
746
    OCTETSTRING enc_message;
747
    if (ec->encrypt(encryption_algotithm::aes_128_ccm, ec->symmetric_encryption_key(), ec->nonce(), p__toBeEncryptedSecuredMessage, enc_message) == -1) {
748
      loggers::get_instance().warning("fx__encryptWithEciesNistp256WithSha256: Failed to encrypt message");
749
      return OCTETSTRING(0, nullptr);
750
    }
751
    enc_message += ec->tag();
752
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesNistp256WithSha256: enc message||Tag: ", enc_message);
753

754
    return enc_message;
755
  }
756

757
758
759
760
  /**
   * @desc Test function for ECIES NIST P-256 Encryption with SHA-256
   * @remark For the purpose of testing, the content of p__toBeEncryptedSecuredMessage is the AES 128 symmetric key to be encrypted
   */
761
  OCTETSTRING fx__test__encryptWithEciesNistp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__privateEphemeralKey, const OCTETSTRING& p__recipientPublicKeyX, const OCTETSTRING& p__recipientPublicKeyY, const OCTETSTRING& p__salt, OCTETSTRING& p__publicEphemeralKeyX, OCTETSTRING& p__publicEphemeralKeyY, OCTETSTRING& p__aes__sym__key, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce) {
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
    
    // 1. Generate new ephemeral Private/Public keys
    security_ecc ec(ec_elliptic_curves::nist_p_256, p__privateEphemeralKey);
    p__publicEphemeralKeyX = ec.public_key_x();
    p__publicEphemeralKeyY = ec.public_key_y();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesNistp256WithSha256: Vx=", p__publicEphemeralKeyX);
    loggers::get_instance().log_msg("fx__test__encryptWithEciesNistp256WithSha256: Vy=", p__publicEphemeralKeyY);
    
    // 2. Generate and derive shared secret
    security_ecc ec_comp(ec_elliptic_curves::nist_p_256, p__recipientPublicKeyX, p__recipientPublicKeyY);
    ec.symmetric_encryption_key(p__toBeEncryptedSecuredMessage);
    loggers::get_instance().log_msg("fx__test__encryptWithEciesNistp256WithSha256: ", ec.encrypted_symmetric_key());
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y(), p__salt) == -1) {
      loggers::get_instance().warning("fx__test__encryptWithEciesNistp256WithSha256: Failed to generate and derive secret key");
      return OCTETSTRING(0, nullptr);
    }
778
779
780
781
782
    
    // Set the AES symmetric key
    loggers::get_instance().log_msg("fx__test__encryptWithEciesNistp256WithSha256: AES symmetric key: ", ec.symmetric_encryption_key());
    p__aes__sym__key = ec.symmetric_encryption_key();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesNistp256WithSha256: p__aes__sym__key: ", p__aes__sym__key);
783
    // Set the encrypted symmetric key
784
    loggers::get_instance().log_msg("fx__test__encryptWithEciesNistp256WithSha256: Encrypted symmetric key: ", ec.encrypted_symmetric_key());
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
    p__encrypted__sym__key = ec.encrypted_symmetric_key();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesNistp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
    // Set the tag of the symmetric key encryption
    p__authentication__vector = ec.tag();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesNistp256WithSha256: p__authentication__vector: ", p__authentication__vector);
    // 3. Retrieve AES 128 parameters
    p__nonce = ec.nonce();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesNistp256WithSha256: p__nonce: ", p__nonce);
    // 4. Encrypt the data using AES-128 CCM
    OCTETSTRING enc_message;
    if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec.symmetric_encryption_key(), ec.nonce(), p__toBeEncryptedSecuredMessage, enc_message) == -1) {
      loggers::get_instance().warning("fx__test__encryptWithEciesNistp256WithSha256: Failed to encrypt message");
      return OCTETSTRING(0, nullptr);
    }
    enc_message += ec.tag();
    loggers::get_instance().log_to_hexa("fx__test__encryptWithEciesNistp256WithSha256: enc message||Tag: ", enc_message);
    
    return enc_message;
  }
  
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  /**
   * \fn OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__privateEncKey, const OCTETSTRING& p__publicEphemeralKeyX, const OCTETSTRING& p__publicEphemeralKeyY, const OCTETSTRING& p__encrypted__sym__key, const OCTETSTRING& p__authentication__vector, const OCTETSTRING& p__nonce);
   * \brief Decrypt the message using ECIES algorithm to decrypt AES 128 CCM symmetric key, as defined in IEEE Std 1609.2-2017
   * \param[in] p__encryptedSecuredMessage The encrypted message
   * \param[in] p__privateEncKey The private encryption key
   * \param[in] p__publicEphemeralKeyCompressed The public ephemeral compressed key
   * \param[in] p__ephemeralCompressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
   * \param[in] p__encrypted__sym__key The encrypted AES 128 symmetric key
   * \param[in] p__authentication__vector The tag of the encrypted AES 128 symmetric key
   * \param[in] p__nonce The nonce vector
   * \return The original message
   * \see IEEE Std 1609.2-2017 Clause 5.3.5 Public key encryption algorithms: ECIES
   * \see https://www.nominet.uk/researchblog/how-elliptic-curve-cryptography-encryption-works/
   * \see http://digital.csic.es/bitstream/10261/32671/1/V2-I2-P7-13.pdf
   */
  // TODO Use common function for both fx__encryptWithEciesxxx and fx__decryptWithEciesxxx function
Yann Garcia's avatar
Yann Garcia committed
821
  OCTETSTRING fx__decryptWithEciesNistp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__privateEncKey, const OCTETSTRING& p__publicEphemeralKeyCompressed, const INTEGER& p__ephemeralCompressedMode, const OCTETSTRING& p__encrypted__sym__key, const OCTETSTRING& p__authentication__vector, const OCTETSTRING& p__nonce, const OCTETSTRING& p__salt, OCTETSTRING& p__aes__sym__enc__key) {
822
823
824
825
826
827
828
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__encryptedSecuredMessage);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__privateEncKey: ", p__privateEncKey);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__publicEphemeralKeyCompressed: ", p__publicEphemeralKeyCompressed);
    loggers::get_instance().log(">>> fx__decryptWithEciesNistp256WithSha256: p__ephemeralCompressedMode: %d", static_cast<int>(p__ephemeralCompressedMode));
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__nonce: ", p__nonce);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__authentication__vector: ", p__authentication__vector);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
829
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesNistp256WithSha256: p__salt", p__salt);
830

831
    // 1. Create security_ecc instance based on recipient's private key
832
833
    security_ecc ec(ec_elliptic_curves::nist_p_256, p__privateEncKey);
    security_ecc ec_comp(ec_elliptic_curves::nist_p_256, p__publicEphemeralKeyCompressed, (static_cast<int>(p__ephemeralCompressedMode) == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
834
    
835
836
    // 2. Generate the shared secret value based on public ephemeral keys will be required
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y(), p__encrypted__sym__key, p__nonce, p__authentication__vector, p__salt) == -1) {
837
      loggers::get_instance().warning("fx__decryptWithEciesNistp256WithSha256: Failed to generate shared secret");
838
      return OCTETSTRING(0, nullptr);
839
840
841
    }
    
    // Decrypt the message
842
843
    OCTETSTRING enc_message(p__encryptedSecuredMessage.lengthof() - ec.tag().lengthof(), static_cast<const unsigned char*>(p__encryptedSecuredMessage)); // Extract the encrypted message
    loggers::get_instance().log_msg("fx__decryptWithEciesNistp256WithSha256: enc_message: ", enc_message); // Extract the ctag value
844
    OCTETSTRING tag(ec.tag().lengthof(), static_cast<const unsigned char*>(p__encryptedSecuredMessage) + p__encryptedSecuredMessage.lengthof() - ec.tag().lengthof());
845
846
    loggers::get_instance().log_msg("fx__decryptWithEciesNistp256WithSha256: tag: ", tag);
    OCTETSTRING message;
847
848
    if (ec.decrypt(tag, enc_message, message) == -1) {
      loggers::get_instance().warning("fx__decryptWithEciesNistp256WithSha256: Failed to generate shared secret");
849
      return OCTETSTRING(0, nullptr);
850
    }
851
    loggers::get_instance().log_msg("fx__decryptWithEciesNistp256WithSha256: dec message: ", message);
Yann Garcia's avatar
Yann Garcia committed
852
853
    p__aes__sym__enc__key = ec.symmetric_encryption_key();
    loggers::get_instance().log_msg("fx__decryptWithEciesNistp256WithSha256: AES 128 encryption key: ", p__aes__sym__enc__key);
854
    
855
    return message;
856
857
  }
  
858
  OCTETSTRING fx__encryptWithEciesBrainpoolp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__recipientsPublicKeyCompressed, const INTEGER& p__compressedMode, const OCTETSTRING& p__salt, OCTETSTRING& p__publicEphemeralKeyCompressed, INTEGER& p__ephemeralCompressedMode,OCTETSTRING& p__aes__sym__key, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce, const BOOLEAN& p__use__hardcoded__values) {
859
860
861
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__toBeEncryptedSecuredMessage);
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__recipientsPublicKeyCompressed: ", p__recipientsPublicKeyCompressed);
    loggers::get_instance().log(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__compressedMode: %d", static_cast<int>(p__compressedMode));
862
863
864
865
866
867
868
869
870
871
872
873
874
    loggers::get_instance().log_msg(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__salt: ", p__salt);
    loggers::get_instance().log(">>> fx__encryptWithEciesBrainpoolp256WithSha256: p__use__hardcoded__values: %x", static_cast<const boolean>(p__use__hardcoded__values));
    
    // 1. Generate new Private/Public Ephemeral key
    std::unique_ptr<security_ecc> ec;
    if (!static_cast<const boolean>(p__use__hardcoded__values)) {
      ec.reset(new security_ecc(ec_elliptic_curves::brainpool_p_256_r1));
      if (ec->generate() == -1) {
        loggers::get_instance().warning("fx__encryptWithEciesBrainpoolp256WithSha256: Failed to generate ephemeral keys");
        return OCTETSTRING(0, nullptr);
      }
    } else {
      ec.reset(new security_ecc(ec_elliptic_curves::brainpool_p_256_r1, str2oct("0722B39ABC7B6C5301CA0408F454F81553D7FE59F492DBF385B6B6D1F81E0F68"))); // Hardcoded private key
875
    }
876
    // 2. Generate and derive shared secret based on recipient's private keys
877
    security_ecc ec_comp(ec_elliptic_curves::brainpool_p_256_r1, p__recipientsPublicKeyCompressed, (static_cast<int>(p__compressedMode) == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
878
879
880
881
    if (static_cast<const boolean>(p__use__hardcoded__values)) { // Set AES encryption key to an harcoded value
      ec->symmetric_encryption_key(str2oct("5A4E63B247C714644E85CAC49BD26C81"));
    }
    if (ec->generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y(), p__salt) == -1) {
882
      loggers::get_instance().warning("fx__encryptWithEciesBrainpoolp256WithSha256: Failed to generate and derive secret key");
883
      return OCTETSTRING(0, nullptr);
884
    }
885
    
886
    // Set the AES symmetric key
887
888
    loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: AES symmetric key: ", ec->symmetric_encryption_key());
    p__aes__sym__key = ec->symmetric_encryption_key();
889
    loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: p__aes__sym__key: ", p__aes__sym__key);
890
    // Set the encrypted symmetric key
891
892
893
    loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: Encrypted symmetric key: ", ec->encrypted_symmetric_key());
    p__encrypted__sym__key = ec->encrypted_symmetric_key();
    loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
894
    // Set the tag of the symmetric key encryption
895
    p__authentication__vector = ec->tag();
896
    loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: p__authentication__vector: ", p__authentication__vector);
897
    // Set ephemeral public keys
898
    p__publicEphemeralKeyCompressed = ec->public_key_compressed();
899
    loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: Ephemeral public compressed key: ", p__publicEphemeralKeyCompressed);
900
    p__ephemeralCompressedMode = (ec->public_key_compressed_mode() == ecc_compressed_mode::compressed_y_0) ? 0 : 1;
901
    loggers::get_instance().log("fx__encryptWithEciesBrainpoolp256WithSha256: Ephemeral public compressed mode: %d: ", p__ephemeralCompressedMode);
902
    // 3. Retrieve AES 128 parameters
903
    p__nonce = ec->nonce();
904
    loggers::get_instance().log_msg("fx__encryptWithEciesBrainpoolp256WithSha256: p__nonce: ", p__nonce);
905
    // 4. Encrypt the data using AES-128 CCM
906
    OCTETSTRING enc_message;
907
    if (ec->encrypt(encryption_algotithm::aes_128_ccm, ec->symmetric_encryption_key(), ec->nonce(), p__toBeEncryptedSecuredMessage, enc_message) == -1) {
908
      loggers::get_instance().warning("fx__encryptWithEciesBrainpoolp256WithSha256: Failed to encrypt message");
909
      return OCTETSTRING(0, nullptr);
910
    }
911
    enc_message += ec->tag();
912
    loggers::get_instance().log_to_hexa("fx__encryptWithEciesBrainpoolp256WithSha256: enc message||Tag: ", enc_message);
913

914
    return enc_message;
915
916
  }

917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
  /**
   * @desc Test function for ECIES BRAINPOOL P-256r1 Encryption with SHA-256
   * @remark For the purpose of testing, the content of p__toBeEncryptedSecuredMessage is the AES 128 symmetric key to be encrypted
   */
  OCTETSTRING fx__test__encryptWithEciesBrainpoolp256WithSha256(const OCTETSTRING& p__toBeEncryptedSecuredMessage, const OCTETSTRING& p__privateEphemeralKey, const OCTETSTRING& p__recipientPublicKeyX, const OCTETSTRING& p__recipientPublicKeyY, const OCTETSTRING& p__salt, OCTETSTRING& p__publicEphemeralKeyX, OCTETSTRING& p__publicEphemeralKeyY, OCTETSTRING& p__aes__sym__key, OCTETSTRING& p__encrypted__sym__key, OCTETSTRING& p__authentication__vector, OCTETSTRING& p__nonce) {
    
    // 1. Generate new ephemeral Private/Public keys
    security_ecc ec(ec_elliptic_curves::brainpool_p_256_r1, p__privateEphemeralKey);
    p__publicEphemeralKeyX = ec.public_key_x();
    p__publicEphemeralKeyY = ec.public_key_y();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: Vx=", p__publicEphemeralKeyX);
    loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: Vy=", p__publicEphemeralKeyY);
    
    // 2. Generate and derive shared secret
    security_ecc ec_comp(ec_elliptic_curves::brainpool_p_256_r1, p__recipientPublicKeyX, p__recipientPublicKeyY);
    ec.symmetric_encryption_key(p__toBeEncryptedSecuredMessage);
    loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: ", ec.encrypted_symmetric_key());
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y(), p__salt) == -1) {
      loggers::get_instance().warning("fx__test__encryptWithEciesBrainpoolp256WithSha256: Failed to generate and derive secret key");
      return OCTETSTRING(0, nullptr);
    }
    
    // Set the AES symmetric key
    loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: AES symmetric key: ", ec.symmetric_encryption_key());
    p__aes__sym__key = ec.symmetric_encryption_key();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: p__aes__sym__key: ", p__aes__sym__key);
    // Set the encrypted symmetric key
    loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: Encrypted symmetric key: ", ec.encrypted_symmetric_key());
    p__encrypted__sym__key = ec.encrypted_symmetric_key();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
    // Set the tag of the symmetric key encryption
    p__authentication__vector = ec.tag();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: p__authentication__vector: ", p__authentication__vector);
    // 3. Retrieve AES 128 parameters
    p__nonce = ec.nonce();
    loggers::get_instance().log_msg("fx__test__encryptWithEciesBrainpoolp256WithSha256: p__nonce: ", p__nonce);
    // 4. Encrypt the data using AES-128 CCM
    OCTETSTRING enc_message;
    if (ec.encrypt(encryption_algotithm::aes_128_ccm, ec.symmetric_encryption_key(), ec.nonce(), p__toBeEncryptedSecuredMessage, enc_message) == -1) {
      loggers::get_instance().warning("fx__test__encryptWithEciesBrainpoolp256WithSha256: Failed to encrypt message");
      return OCTETSTRING(0, nullptr);
    }
    enc_message += ec.tag();
    loggers::get_instance().log_to_hexa("fx__test__encryptWithEciesBrainpoolp256WithSha256: enc message||Tag: ", enc_message);
    
    return enc_message;
  }
  
Yann Garcia's avatar
Yann Garcia committed
965
  OCTETSTRING fx__decryptWithEciesBrainpoolp256WithSha256(const OCTETSTRING& p__encryptedSecuredMessage, const OCTETSTRING& p__privateEncKey, const OCTETSTRING& p__publicEphemeralKeyCompressed, const INTEGER& p__ephemeralCompressedMode, const OCTETSTRING& p__encrypted__sym__key, const OCTETSTRING& p__authentication__vector, const OCTETSTRING& p__nonce, const OCTETSTRING& p__salt, OCTETSTRING& p__aes__sym__enc__key) {
966
967
968
969
970
971
972
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__toBeEncryptedSecuredMessage: ", p__encryptedSecuredMessage);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__privateEncKey: ", p__privateEncKey);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__publicEphemeralKeyCompressed: ", p__publicEphemeralKeyCompressed);
    loggers::get_instance().log(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__ephemeralCompressedMode: %d", static_cast<int>(p__ephemeralCompressedMode));
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__nonce: ", p__nonce);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__authentication__vector: ", p__authentication__vector);
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__encrypted__sym__key: ", p__encrypted__sym__key);
Yann Garcia's avatar
Yann Garcia committed
973
    loggers::get_instance().log_msg(">>> fx__decryptWithEciesBrainpoolp256WithSha256: p__salt", p__salt);
974

975
    // 1. Create security_ecc instance based on public ephemeral keys
976
977
    security_ecc ec(ec_elliptic_curves::brainpool_p_256_r1, p__privateEncKey);
    security_ecc ec_comp(ec_elliptic_curves::brainpool_p_256_r1, p__publicEphemeralKeyCompressed, (static_cast<int>(p__ephemeralCompressedMode) == 0) ? ecc_compressed_mode::compressed_y_0 : ecc_compressed_mode::compressed_y_1);
978

979
980
    // 2. Generate the shared secret value based on public ephemeral keys will be required
    if (ec.generate_and_derive_ephemeral_key(encryption_algotithm::aes_128_ccm, ec_comp.public_key_x(), ec_comp.public_key_y(), p__encrypted__sym__key, p__nonce, p__authentication__vector, OCTETSTRING(0, nullptr)) == -1) {
981
      loggers::get_instance().warning("fx__decryptWithEciesBrainpoolp256WithSha256: Failed to generate shared secret");
982
      return OCTETSTRING(0, nullptr);
983
984
    }

985
986
987
    // Decrypt the message
    OCTETSTRING enc_message(p__encryptedSecuredMessage.lengthof() - ec.tag().lengthof(), static_cast<const unsigned char*>(p__encryptedSecuredMessage)); // Extract the encrypted message
    loggers::get_instance().log_msg("fx__decryptWithEciesBrainpoolp256WithSha256: enc_message: ", enc_message); // Extract the ctag value
988
    OCTETSTRING tag(ec.tag().lengthof(), static_cast<const unsigned char*>(p__encryptedSecuredMessage) + p__encryptedSecuredMessage.lengthof() - ec.tag().lengthof());
989
990
    loggers::get_instance().log_msg("fx__decryptWithEciesBrainpoolp256WithSha256: tag: ", tag);
    OCTETSTRING message;
991
992
    if (ec.decrypt(tag, enc_message, message) == -1) {
      loggers::get_instance().warning("fx__decryptWithEciesBrainpoolp256WithSha256: Failed to generate shared secret");