Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/**
* @author ETSI / STF481 / STF507 / STF517 / STF538 / STF545
* @version $Url$
* $Id$
* @desc Module containing functions for Security Protocol
* @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.
*
*/
module LibItsSecurity_Functions {
// Libcommon
import from LibCommon_BasicTypesAndValues all;
import from LibCommon_DataStrings all;
// LibIts
import from IEEE1609dot2BaseTypes language "ASN.1:1997" all;
import from IEEE1609dot2 language "ASN.1:1997" all;
import from EtsiTs103097Module language "ASN.1:1997" all;
// LibItsCommon
//import from LibItsCommon_Functions all;
//import from LibItsCommon_TypesAndValues all;
import from LibItsCommon_Pixits all;
// LibItsSecurity
import from LibItsSecurity_TypesAndValues all;
import from LibItsSecurity_Templates all;
import from LibItsSecurity_Pixits all;
import from LibItsSecurity_Pics all;
import from LibItsSecurity_TestSystem all;
group helpersFunctions {
/**
* @desc Produces a 256-bit (32-byte) hash value
* @param p_toBeHashedData Data to be used to calculate the hash value
* @return The hash value
*/
function f_hashWithSha256(
in octetstring p_toBeHashedData
) return Oct32 {
return fx_hashWithSha256(p_toBeHashedData);
} // End of function f_hashWithSha256
/**
* @desc Produces a 384-bit (48-byte) hash value
* @param p_toBeHashedData Data to be used to calculate the hash value
* @return The hash value
*/
function f_hashWithSha384(
in octetstring p_toBeHashedData
) return Oct48 {
return fx_hashWithSha384(p_toBeHashedData);
} // End of function f_hashWithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on standard IEEE 1609.2
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @param p_privateKey The private key for signature
* @return The signature value
*/
function f_signWithEcdsaNistp256WithSha256(
in octetstring p_toBeSignedSecuredMessage,
in Oct32 p_certificateIssuer,
in Oct32 p_privateKey
) return octetstring {
log(">>> f_signWithEcdsaNistp256WithSha256: p_toBeSignedSecuredMessage= ", p_toBeSignedSecuredMessage);
log(">>> f_signWithEcdsaNistp256WithSha256: p_certificateIssuer= ", p_certificateIssuer);
log(">>> f_signWithEcdsaNistp256WithSha256: p_privateKey= ", p_privateKey);
return fx_signWithEcdsaNistp256WithSha256(
p_toBeSignedSecuredMessage,
p_certificateIssuer,
p_privateKey
);
} // End of function f_signWithEcdsaNistp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on standard IEEE 1609.2
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @param p_privateKey The private key for signature
* @return The signature value
*/
function f_signWithEcdsaBrainpoolp256r1WithSha256(
in octetstring p_toBeSignedSecuredMessage,
in Oct32 p_certificateIssuer,
in Oct32 p_privateKey
) return octetstring {
return fx_signWithEcdsaBrainpoolp256r1WithSha256(
p_toBeSignedSecuredMessage,
p_certificateIssuer,
p_privateKey
);
} // End of function f_signWithEcdsaBrainpoolp256r1WithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature based on standard IEEE 1609.2
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @param p_privateKey The private key for signature
* @return The signature value
*/
function f_signWithEcdsaBrainpoolp384r1WithSha384(
in octetstring p_toBeSignedSecuredMessage,
in Oct48 p_certificateIssuer,
in Oct48 p_privateKey
) return octetstring {
log(">>> f_signWithEcdsaBrainpoolp384r1WithSha384: ", p_toBeSignedSecuredMessage);
log(">>> f_signWithEcdsaBrainpoolp384r1WithSha384: ", p_certificateIssuer);
log(">>> f_signWithEcdsaBrainpoolp384r1WithSha384: ", p_privateKey);
return fx_signWithEcdsaBrainpoolp384r1WithSha384(
p_toBeSignedSecuredMessage,
p_certificateIssuer,
p_privateKey
);
} // End of function f_signWithEcdsaBrainpoolp384r1WithSha384
125
126
127
128
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
function f_decrypt(
in octetstring p_encryptPrivateKey,
in EtsiTs103097Data p_encrypedSecuredMessage,
in octetstring p_salt,
out EtsiTs103097Data p_decrypedSecuredMessage,
out octetstring p_aes_sym_enc_key
) return boolean {
if (ischosen(p_encrypedSecuredMessage.content.encryptedData)) {
var PKRecipientInfo v_pKRecipientInfo;
var RecipientInfo v_recipientInfo := p_encrypedSecuredMessage.content.encryptedData.recipients[0];
var octetstring v_decryptedSecuredMessage;
log(">>> f_decrypt: p_encryptPrivateKey=", p_encryptPrivateKey);
log(">>> f_decrypt: p_encrypedSecuredMessage=", p_encrypedSecuredMessage);
log(">>> f_decrypt: p_salt=", p_salt);
// Check the private encryption key
if (not(isbound(p_encryptPrivateKey))) {
log("*** " & testcasename() & ":ERROR: Failed to load encryption private key ***");
return false;
}
if (ischosen(v_recipientInfo.certRecipInfo)) {
v_pKRecipientInfo := p_encrypedSecuredMessage.content.encryptedData.recipients[0].certRecipInfo;
// Read the certificate based on the recipientId
} else if (ischosen(v_recipientInfo.signedDataRecipInfo)) {
v_pKRecipientInfo := p_encrypedSecuredMessage.content.encryptedData.recipients[0].signedDataRecipInfo;
// Read the certificate based on the recipientId
} else {
log("*** " & testcasename() & ":ERROR: Unsupported RecipientInfo variant ***");
return false;
}
log("f_decrypt: v_pKRecipientInfo=", v_pKRecipientInfo);
if (isbound(v_pKRecipientInfo)) {
if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256)) {
var SymmetricCiphertext v_ciphertext := p_encrypedSecuredMessage.content.encryptedData.ciphertext;
log("f_decrypt: v_ciphertext=", v_ciphertext);
if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_0)) {
v_decryptedSecuredMessage := f_decryptWithEciesNistp256WithSha256(
v_ciphertext.aes128ccm.ccmCiphertext,
p_encryptPrivateKey,
v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_0,
0,
v_pKRecipientInfo.encKey.eciesNistP256.c,
v_pKRecipientInfo.encKey.eciesNistP256.t,
v_ciphertext.aes128ccm.nonce,
p_salt,
p_aes_sym_enc_key
);
} else if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_1)) {
v_decryptedSecuredMessage := f_decryptWithEciesNistp256WithSha256(
v_ciphertext.aes128ccm.ccmCiphertext,
p_encryptPrivateKey,
v_pKRecipientInfo.encKey.eciesNistP256.v.compressed_y_1,
1,
v_pKRecipientInfo.encKey.eciesNistP256.c,
v_pKRecipientInfo.encKey.eciesNistP256.t,
v_ciphertext.aes128ccm.nonce,
p_salt,
p_aes_sym_enc_key
);
} else {
log("*** " & testcasename() & ":ERROR: Non canonical ephemeral encryption keys ***");
return false;
}
if (isbound(v_decryptedSecuredMessage)) {
var bitstring v_decode := oct2bit(v_decryptedSecuredMessage);
if (decvalue(v_decode, p_decrypedSecuredMessage) == 0) {
return true;
} else {
log("*** " & testcasename() & ":ERROR: Faild to decode secured message ***");
}
}
} else if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1)) {
var SymmetricCiphertext v_ciphertext := p_encrypedSecuredMessage.content.encryptedData.ciphertext;
if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_0)) {
v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256r1WithSha256(
v_ciphertext.aes128ccm.ccmCiphertext,
p_encryptPrivateKey,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_0,
0,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.c,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.t,
v_ciphertext.aes128ccm.nonce,
p_salt, p_aes_sym_enc_key
);
} else if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_1)) {
v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256r1WithSha256(
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
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
343
344
345
346
v_ciphertext.aes128ccm.ccmCiphertext,
p_encryptPrivateKey,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_1,
1,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.c,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.t,
v_ciphertext.aes128ccm.nonce,
p_salt,
p_aes_sym_enc_key
);
} else {
log("*** " & testcasename() & ":ERROR: Non canonical ephemeral encryption keys ***");
return false;
}
} else {
log("*** " & testcasename() & ":ERROR: Non canonical ephemeral encryption keys ***");
return false;
}
// TODO else, other variants shall be processed here if
} else {
log("*** " & testcasename() & ":ERROR: Invalid recipient info ***");
return false;
}
if (isbound(v_decryptedSecuredMessage)) {
var bitstring v_decode := oct2bit(v_decryptedSecuredMessage);
if (decvalue(v_decode, p_decrypedSecuredMessage) == 0) {
return true;
} else {
log("*** " & testcasename() & ":ERROR: Faild to decode secured message ***");
}
}
} else {
log("*** " & testcasename() & ":ERROR: Message not encrypted ***");
}
return false;
} // End of function f_decrypt
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) encryption using Nist-P256 algorithm
* @param p_toBeEncryptedSecuredMessage The data to be encrypted
* @param p_recipientsPublicKeyCompressed The Recipient's compressed public key
* @param p_compressed_mode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @param p_publicEphemeralKeyCompressed The generated ephemeral compressed key
* @param p_ephemeralKeyModeCompressed The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @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
* @return The encrypted message
*/
function f_encryptWithEciesNistp256WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyCompressed,
in integer p_compressed_mode,
in octetstring p_salt,
out Oct32 p_publicEphemeralKeyCompressed,
out integer p_ephemeralKeyModeCompressed,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce
) return octetstring {
return fx_encryptWithEciesNistp256WithSha256(
p_toBeEncryptedSecuredMessage,
p_recipientsPublicKeyCompressed,
p_compressed_mode,
p_salt,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
p_aes_sym_key,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // End of function f_encryptWithEciesNistp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) decryption using Nist-P256 algorithm
* @param p_encryptedSecuredMessage The data to be decrypted
* @param p_publicEphemeralKeyCompressed The generated ephemeral compressed key
* @param p_ephemeralKeyModeCompressed The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The decrypted 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
*/
function f_decryptWithEciesNistp256WithSha256(
in octetstring p_encryptedSecuredMessage,
in Oct32 p_privateEncKey,
in Oct32 p_publicEphemeralKeyCompressed,
in integer p_ephemeralKeyModeCompressed,
in Oct16 p_encrypted_sym_key,
in Oct16 p_authentication_vector,
in Oct12 p_nonce,
in Oct32 p_salt,
out Oct16 p_aes_sym_enc_key
) return octetstring {
return fx_decryptWithEciesNistp256WithSha256(
p_encryptedSecuredMessage,
p_privateEncKey,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce,
p_salt,
p_aes_sym_enc_key
);
} // End of function f_decryptWithEcdsaNistp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) encryption using Brainpool-P256 algorithm
* @param p_toBeEncryptedSecuredMessage The data to be encrypted
* @param p_recipientsPublicKeyCompressed The Recipient's compressed public key
* @param p_compressed_mode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @param p_publicEphemeralKeyCompressed The generated ephemeral compressed key
* @param p_ephemeralKeyModeCompressed The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The encrypted 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
*/
function f_encryptWithEciesBrainpoolp256r1WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyCompressed,
in integer p_compressed_mode,
in octetstring p_salt,
out Oct32 p_publicEphemeralKeyCompressed,
out integer p_ephemeralKeyModeCompressed,
out Oct16 p_aes_sym_key,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce
) return octetstring {
return fx_encryptWithEciesBrainpoolp256r1WithSha256(
p_toBeEncryptedSecuredMessage,
p_recipientsPublicKeyCompressed,
p_compressed_mode,
p_salt,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
p_aes_sym_key,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // End of function f_encryptWithEciesBrainpoolp256r1WithSha256
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) decryption using Brainpool-P256 algorithm
* @param p_encryptedSecuredMessage The data to be decrypted
* @param p_publicEphemeralKeyCompressed The generated ephemeral compressed key
* @param p_ephemeralKeyModeCompressed The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @param p_encrypted_sym_key The encrypted AES 128 CCM symmetric key
* @param p_authentication_vector The tag of the AES 128 CCM symmetric key encryption
* @param p_nonce The nonce vector of the AES 128 CCM symmetric key encryption
* @return The decrypted 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
*/
function f_decryptWithEciesBrainpoolp256r1WithSha256(
in octetstring p_encryptedSecuredMessage,
in Oct32 p_privateEncKey,
in Oct32 p_publicEphemeralKeyCompressed,
in integer p_ephemeralKeyModeCompressed,
in Oct16 p_encrypted_sym_key,
in Oct16 p_authentication_vector,
in Oct12 p_nonce,
in Oct32 p_salt,
out Oct16 p_aes_sym_enc_key
) return octetstring {
return fx_decryptWithEciesBrainpoolp256r1WithSha256(
p_encryptedSecuredMessage,
p_privateEncKey,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce,
p_salt,
p_aes_sym_enc_key
);
} // End of function f_decryptWithEcdsaBrainpoolp256r1WithSha256
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
/**
* @desc Compute the HashedId8 value from the hash value
* @param p_hash The hash value
* @return The HashedId8 value
* @verdict
*/
function f_hashedId8FromSha256(
in Oct32 p_hash
) return HashedId8 {
return substr(p_hash, lengthof(p_hash) - 8, 8);
} // End of function f_hashedId8FromSha256
/**
* @desc Compute the HashedId8 value from the hash value
* @param p_hash The hash value
* @return The HashedId8 value
* @verdict
*/
function f_hashedId8FromSha384(
in Oct48 p_hash
) return HashedId8 {
return substr(p_hash, lengthof(p_hash) - 8, 8);
} // End of function f_hashedId8FromSha384
/**
* @desc Compute the HashedId3 value from the HashedId8 value
* @param p_hashp_hashedId8 The HashedId8 value
* @return The HashedId3 value
* @verdict Unchanged
*/
function f_hashedId3FromHashedId8(
in HashedId8 p_hashedId8
) return HashedId3 {
return substr(p_hashedId8, lengthof(p_hashedId8) - 3, 3);
} // End of function f_hashedId3FromHashedId8
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @param p_signature The signature
* @param p_ecdsaNistp256PublicKeyCompressed The compressed public key
* @param p_compressed_mode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaNistp256WithSha256(
in octetstring p_toBeVerifiedData,
in Oct32 p_certificateIssuer,
in Oct64 p_signature,
in Oct32 p_ecdsaNistp256PublicKeyCompressed,
in integer p_compressed_mode
) return boolean {
// log("f_verifyWithEcdsaNistp256WithSha256: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaNistp256WithSha256: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaNistp256WithSha256: signature", p_signature);
// log("f_verifyWithEcdsaNistp256WithSha256: ecdsaNistp256PublicKeyCompressed", p_ecdsaNistp256PublicKeyCompressed);
return fx_verifyWithEcdsaNistp256WithSha256(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaNistp256PublicKeyCompressed,
p_compressed_mode
);
} // End of function f_verifyWithEcdsaNistp256WithSha256
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @param p_signature The signature
* @param p_ecdsaNistp256PublicKeyX The public key (x coordinate)
* @param p_ecdsaNistp256PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaNistp256WithSha256_1( // TODO To be removed
in octetstring p_toBeVerifiedData,
in Oct32 p_certificateIssuer,
in Oct64 p_signature,
in Oct32 p_ecdsaNistp256PublicKeyX,
in Oct32 p_ecdsaNistp256PublicKeyY
) return boolean {
// log("f_verifyWithEcdsaNistp256WithSha256: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaNistp256WithSha256: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaNistp256WithSha256: signature", p_signature);
// log("f_verifyWithEcdsaNistp256WithSha256: ecdsaNistp256PublicKeyX", p_ecdsaNistp256PublicKeyX);
// log("f_verifyWithEcdsaNistp256WithSha256: ecdsaNistp256PublicKeyY", p_ecdsaNistp256PublicKeyY);
return fx_verifyWithEcdsaNistp256WithSha256_1(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaNistp256PublicKeyX,
p_ecdsaNistp256PublicKeyY);
} // End of function f_verifyWithEcdsaNistp256WithSha256_1
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @param p_signature The signature
* @param p_ecdsaBrainpoolp256PublicKeyCompressed The compressed public key
* @param p_compressed_mode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp256r1WithSha256(
in octetstring p_toBeVerifiedData,
in Oct32 p_certificateIssuer,
in Oct64 p_signature,
in Oct32 p_ecdsaBrainpoolp256PublicKeyCompressed,
in integer p_compressed_mode
) return boolean {
log("f_verifyWithEcdsaBrainpoolp256r1WithSha256: toBeVerifiedData", p_toBeVerifiedData);
log("f_verifyWithEcdsaBrainpoolp256r1WithSha256: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
log("f_verifyWithEcdsaBrainpoolp256r1WithSha256: signature", p_signature);
log("f_verifyWithEcdsaBrainpoolp256r1WithSha256: ecdsaBrainpoolp256PublicKeyCompressed", p_ecdsaBrainpoolp256PublicKeyCompressed);
return fx_verifyWithEcdsaBrainpoolp256r1WithSha256(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp256PublicKeyCompressed,
p_compressed_mode
);
} // End of function f_verifyWithEcdsaBrainpoolp256r1WithSha256
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @param p_signature The signature
* @param p_ecdsaBrainpoolp256PublicKeyX The public key (x coordinate)
* @param p_ecdsaBrainpoolp256PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp256r1WithSha256_1( // TODO To be removed
in octetstring p_toBeVerifiedData,
in Oct32 p_certificateIssuer,
in Oct64 p_signature,
in Oct32 p_ecdsaBrainpoolp256PublicKeyX,
in Oct32 p_ecdsaBrainpoolp256PublicKeyY
) return boolean {
// log("f_verifyWithEcdsaBrainpoolp256r1WithSha256: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaBrainpoolp256r1WithSha256: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaBrainpoolp256r1WithSha256: signature", p_signature);
// log("f_verifyWithEcdsaBrainpoolp256r1WithSha256: ecdsaBrainpoolp256PublicKeyX", p_ecdsaBrainpoolp256PublicKeyX);
// log("f_verifyWithEcdsaBrainpoolp256r1WithSha256: ecdsaBrainpoolp256PublicKeyY", p_ecdsaBrainpoolp256PublicKeyY);
return fx_verifyWithEcdsaBrainpoolp256r1WithSha256_1(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp256PublicKeyX,
p_ecdsaBrainpoolp256PublicKeyY);
} // End of function f_verifyWithEcdsaBrainpoolp256r1WithSha256_1
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @param p_signature The signature
* @param p_ecdsaBrainpoolp384PublicKeyX The public key (x coordinate)
* @param p_ecdsaBrainpoolp384PublicKeyY The public key (y coordinate)
* @param p_compressed_mode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp384r1WithSha384(
in octetstring p_toBeVerifiedData,
in Oct48 p_certificateIssuer,
in Oct96 p_signature,
in Oct48 p_ecdsaBrainpoolp384PublicKeyCompressed,
in integer p_compressed_mode
) return boolean {
// log("f_verifyWithEcdsaBrainpoolp384r1WithSha384: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaBrainpoolp384r1WithSha384: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaBrainpoolp384r1WithSha384: signature", p_signature);
// log("f_verifyWithEcdsaBrainpoolp384r1WithSha384: ecdsaBrainpoolp384PublicKeyCompressed", p_ecdsaBrainpoolp384PublicKeyCompressed);
return fx_verifyWithEcdsaBrainpoolp384r1WithSha384(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp384PublicKeyCompressed,
p_compressed_mode
);
} // End of function f_verifyWithEcdsaBrainpoolp384r1WithSha384
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @param p_signature The signature
* @param p_ecdsaBrainpoolp384PublicKeyX The public key (x coordinate)
* @param p_ecdsaBrainpoolp384PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp384r1WithSha384_1( // TODO To be removed
in octetstring p_toBeVerifiedData,
in Oct48 p_certificateIssuer,
in Oct96 p_signature,
in Oct48 p_ecdsaBrainpoolp384PublicKeyX,
in Oct48 p_ecdsaBrainpoolp384PublicKeyY
) return boolean {
// log("f_verifyWithEcdsaBrainpoolp384r1WithSha384: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaBrainpoolp384r1WithSha384: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaBrainpoolp384r1WithSha384: signature", p_signature);
// log("f_verifyWithEcdsaBrainpoolp384r1WithSha384: ecdsaBrainpoolp384PublicKeyX", p_ecdsaBrainpoolp384PublicKeyX);
// log("f_verifyWithEcdsaBrainpoolp384r1WithSha384: ecdsaBrainpoolp384PublicKeyY", p_ecdsaBrainpoolp384PublicKeyY);
return fx_verifyWithEcdsaBrainpoolp384r1WithSha384_1(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp384PublicKeyX,
p_ecdsaBrainpoolp384PublicKeyY);
} // End of function f_verifyWithEcdsaBrainpoolp384r1WithSha384_1
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
/**
* @desc Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
* This function should not be used by the ATS
* @param p_privateKey The new private key value
* @param p_publicKeyX The new public key value (x coordinate)
* @param p_publicKeyX The new public key value (y coordinate)
* @param p_publicKeyCompressed The compressed public keys
* @param p_compressed_mode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_generate_key_pair_nistp256(
out Oct32 p_privateKey,
out Oct32 p_publicKeyX,
out Oct32 p_publicKeyY,
out Oct32 p_publicKeyCompressed,
out integer p_compressed_mode
) return boolean {
log(">>> f_generate_key_pair_nistp256");
return fx_generateKeyPair_nistp256(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressed_mode);
}
/**
* @desc Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
* This function should not be used by the ATS
* @param p_privateKey The new private key value
* @param p_publicKeyX The new public key value (x coordinate)
* @param p_publicKeyX The new public key value (y coordinate)
* @param p_publicKeyCompressed The compressed public keys
* @param p_compressed_mode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_generate_key_pair_brainpoolp256r1(
out Oct32 p_privateKey,
out Oct32 p_publicKeyX,
out Oct32 p_publicKeyY,
out Oct32 p_publicKeyCompressed,
out integer p_compressed_mode
) return boolean {
log(">>> f_generate_key_pair_brainpoolp256r1");
return fx_generateKeyPair_brainpoolp256r1(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressed_mode);
}
/**
* @desc Produce a new public/private key pair based on Elliptic Curve Digital Signature Algorithm (ECDSA) algorithm.
* This function should not be used by the ATS
* @param p_privateKey The new private key value
* @param p_publicKeyX The new public key value (x coordinate)
* @param p_publicKeyX The new public key value (y coordinate)
* @param p_publicKeyCompressed The compressed public keys
* @param p_compressed_mode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_generate_key_pair_brainpoolp384r1(
out Oct48 p_privateKey,
out Oct48 p_publicKeyX,
out Oct48 p_publicKeyY,
out Oct48 p_publicKeyCompressed,
out integer p_compressed_mode
) return boolean {
return fx_generateKeyPair_brainpoolp384r1(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressed_mode);
}
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
/**
* @desc Calculate digest over the certificate
* @param p_cert The certificate
* @return the HashedId8 value
* @see Draft ETSI TS 103 097 V1.1.14 Clause 4.2.13 HashedId8
*/
function f_calculateDigestFromCertificate(
in Certificate p_cert
) return HashedId8 {
var octetstring v_hash;
if (PICS_SEC_SHA256) {
v_hash := f_calculateDigestSha256FromCertificate(p_cert);
} if (PICS_SEC_SHA384) {
v_hash := f_calculateDigestSha384FromCertificate(p_cert);
}
return substr(v_hash, lengthof(v_hash) - 8, 8);
} // End of function f_calculateDigestFromCertificate
/**
* @desc Calculate digest over the certificate
* @param p_cert The certificate
* @return the HashedId8 value
* @see Draft ETSI TS 103 097 V1.1.14 Clause 4.2.13 HashedId8
*/
function f_calculateDigestSha256FromCertificate(
in EtsiTs103097Certificate p_cert
) return HashedId8 {
var octetstring v_toBeHashedData;
var octetstring v_hash;
v_toBeHashedData := bit2oct(encvalue(p_cert));
v_hash := f_hashWithSha256(v_toBeHashedData);
return substr(v_hash, lengthof(v_hash) - 8, 8);
} // End of function f_calculateDigestSha256FromCertificate
function f_calculateDigestSha384FromCertificate(
in EtsiTs103097Certificate p_cert
) return HashedId8 {
var octetstring v_toBeHashedData;
var octetstring v_hash;
v_toBeHashedData := bit2oct(encvalue(p_cert));
v_hash := f_hashWithSha384(v_toBeHashedData);
return substr(v_hash, lengthof(v_hash) - 8, 8);
} // End of function f_calculateDigestSha384FromCertificate
function f_duration2time(
in Duration p_duration
) return UInt16 {
if (ischosen(p_duration.seconds)) {
return p_duration.seconds;
} else if (ischosen(p_duration.minutes)) {
return p_duration.minutes;
} else if (ischosen(p_duration.hours)) {
return p_duration.hours;
} else if (ischosen(p_duration.sixtyHours)) {
return p_duration.sixtyHours;
} else if (ischosen(p_duration.years)) {
return p_duration.years;
}
return 0; // Unrechable code
} // End of function f_duration2time
group hostSignatureHelpers {
/**
* @desc Initialize [out] certificates according to the specified certificate name
* @param p_certificateName The certificate name to be used
* @param p_aaCertificate The AA certificate [out]
* @param p_atCertificate The AT certificate [out]
* @return true on succes, false otherwise
* @see Draft ETSI TS 103 097 V1.1.14 Clause 4.2.13 HashedId8
*/
function f_prepareCertificates(
in template (omit) charstring p_certificateName,
out EtsiTs103097Certificate p_aaCertificate,
out EtsiTs103097Certificate p_atCertificate
) runs on ItsSecurityBaseComponent return boolean {
//log(">>> f_prepareCertificates: ", p_certificateName);
// Load certificates if required
if ((lengthof(p_certificateName) > 0) and (valueof(p_certificateName) != cc_taCert_A)) {
var HashedId8 v_digest;
var charstring v_cert;
if (f_readCertificate(valueof(p_certificateName), p_atCertificate) == false){
log("f_prepareCertificates: Failed to read certificate ", p_certificateName);
return false;
}
if (ischosen(p_atCertificate.issuer.sha256AndDigest)) {
v_digest := p_atCertificate.issuer.sha256AndDigest;
} else if (ischosen(p_atCertificate.issuer.sha384AndDigest)) {
v_digest := p_atCertificate.issuer.sha384AndDigest;
} else {
log("f_prepareCertificates: Invalid certificate issuer ", p_atCertificate.issuer);
return false;
}
if (f_getCertificateFromDigest(v_digest, p_aaCertificate, v_cert) == false) {
log("f_prepareCertificates: Failed to read certificate issuer ", v_digest);
return false;
}
} else {
p_atCertificate := vc_atCertificate;
p_aaCertificate := vc_aaCertificate;
}
// Store the certificate to build this message
vc_lastAtCertificateUsed := p_atCertificate;
return true;
} // End of function f_prepareCertificates
/**
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_securedMessage The signed SecureMessage part
* @param p_payloadField Payloads to be included in the message
* @param p_mandatoryHeaders Mandatory headers for the selected profile
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_securityProfile Selected security profile
* @return true on success, false otherwise
*/
function f_buildGnSecuredMessage(
inout EtsiTs103097Data p_securedMessage,
in charstring p_certificateName,
in ToBeSignedData p_payloadField
) runs on ItsSecurityBaseComponent return boolean {
// Local variables
var octetstring v_secPayload, v_signature;
var ToBeSignedData v_toBeSignedData;
var octetstring v_certificateIssuer;
var octetstring v_privateKey;
log(">>> f_buildGnSecuredMessage: p_securedMessage=", p_securedMessage);
log(">>> f_buildGnSecuredMessage: p_payloadField=", p_payloadField);
// Prepare payload to be signed
v_toBeSignedData := valueof(p_payloadField);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
log("f_buildGnSecuredMessage: v_secPayload=", v_secPayload);
// Signed payload
if (ispresent(p_certificateName) and (valueof(p_certificateName) != cc_taCert_A)) {
if(not f_readSigningKey(valueof(p_certificateName), v_privateKey)){
return false;
}
} else {
if(not f_readSigningKey(cc_taCert_A, v_privateKey)){
return false;
}
}
// log("f_buildGnSecuredMessage: v_privateKey=", v_privateKey);
f_getCertificateHash(p_certificateName, v_certificateIssuer);
if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature)) {
v_signature := f_signWithEcdsaNistp256WithSha256(
v_secPayload,
v_certificateIssuer,
v_privateKey
);
p_securedMessage.content.signedData.signature_ := valueof(m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(substr(v_signature, 0, 32)),
substr(v_signature, 32, 32)
)
));
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP256r1Signature)) {
v_signature := f_signWithEcdsaBrainpoolp256r1WithSha256(
v_secPayload,
v_certificateIssuer,
v_privateKey
);
p_securedMessage.content.signedData.signature_ := valueof(m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(substr(v_signature, 0, 32)),
substr(v_signature, 32, 32)
)
));
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) {
v_signature := f_signWithEcdsaBrainpoolp384r1WithSha384(
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
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
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
v_secPayload,
v_certificateIssuer,
v_privateKey
);
p_securedMessage.content.signedData.signature_ := valueof(m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(substr(v_signature, 0, 48)),
substr(v_signature, 48, 48)
)
));
} // TODO To be continued
// log("<<< f_buildGnSecuredMessage: p_securedMessage=", p_securedMessage);
return true;
} // End of function f_buildGnSecuredMessage
/**
* @desc This function build and sign the SecureMessage part covered by the signature process including wrong elements of protocols. It is used for BO test cases
* @param p_securedMessage The signed SecureMessage part
* @param p_certificateName The certificate name
* @param p_protocolVersion The protocol version to be set. Default: 2
* @param p_trailerStatus The Traile behaviour:
* <li>0 for no trailer</li>
* <li>1 for invalid trailer</li>
* <li>2 for duplicated trailer</li>
* @param p_payloadField Payloads to be included in the message
* @param p_mandatoryHeaders Mandatory headers for the selected profile
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_securityProfile Selected security profile
* @return true on success, false otherwise
*/
function f_buildGnSecuredMessage_Bo(
inout EtsiTs103097Data p_securedMessage,
in template (value) charstring p_certificateName,
in UInt8 p_protocolVersion := c_protocol_version,
in integer p_trailerStatus := 0,
in template (value) ToBeSignedData p_payloadField,
in template (value) HeaderInfo p_mandatoryHeaders,
in template (omit) HeaderInfo p_headerInfo := omit
) return boolean {
// Local variables
var octetstring v_secPayload, v_signature;
var template (value) ToBeSignedData v_toBeSignedData;
var integer i, j, k, n;
var HeaderInfo v_headerFields;
var Ieee1609Dot2Content v_toBeSignedPayload;
var Oct32 v_privateKey;
var UInt8 v_trailerSize;
// Prepare headers
if (not(ispresent(p_headerInfo))) {
v_headerFields := valueof(p_mandatoryHeaders);
} else {/* FIXME To be reviewed
// Merge p_headerInfo and v_mandatoryHeaders into v_headerFields
i := 0; // index for p_headerInfo
j := 0; // index for v_mandatoryHeaders
k := 0; // index for v_headerFields
// Special processing for signer_info
if (lengthof(valueof(p_headerInfo)) > 0 and valueof(p_headerInfo[i].type_) == e_signer_info) {
v_headerFields[k] := valueof(p_headerInfo[i]);
k := k + 1;
i := i + 1;
}
for (j := j; j < lengthof(p_mandatoryHeaders); j := j + 1) {
// Search for mandatory header in p_HeaderFields
for (n := 0; n < lengthof(p_headerInfo); n := n + 1) {
if (valueof(p_headerInfo[n].type_) == valueof(p_mandatoryHeaders[j].type_)) {
// mandatory header already in p_HeaderFields
break;
}
} // End of 'for' statement
if (n >= lengthof(p_headerInfo)) {
if (valueof(p_mandatoryHeaders[j].type_) != e_signer_info) {
// Add headers from p_headerInfo having lower number than mandatory header
for (n := i; n < lengthof(p_headerInfo) and valueof(p_headerInfo[n].type_) < valueof(p_mandatoryHeaders[j].type_); n := n + 1) {
v_headerFields[k] := valueof(p_headerInfo[n]);
k := k + 1;
i := i + 1;
}
}
// Add mandatory header
v_headerFields[k] := valueof(p_mandatoryHeaders[j]);
k := k + 1;
}
} // End of 'for' statement
// Add remaining headers from p_HeaderFields
for ( i := i; i < lengthof(p_headerInfo); i := i + 1) {
// Add headers from p_headerInfo having lower number than mandatory header
v_headerFields[k] := valueof(p_headerInfo[i]);
k := k + 1;
} // End of 'for' statement
*/}
// Prepare payload to be signed
/* FIXME To be reviewed v_toBeSignedPayload := valueof(p_payloadField);
// log("p_trailerStatus=", p_trailerStatus);
if (p_trailerStatus == 0) {
v_trailerSize := 0;
} else if (p_trailerStatus == 1) {
v_trailerSize := 67;
} else if (p_trailerStatus == 2) {
v_trailerSize := 2 * 67;
} else {
v_trailerSize := 67;
}
v_toBeSignedData := m_toBeSignedSecuredMessage_wrong_protocol(
v_headerFields,
v_toBeSignedPayload,
e_signature,
p_protocolVersion,
v_trailerSize
);*/
// log("m_toBeSignedSecuredMessage_wrong_protocol=", v_toBeSignedData);
/* FIXME To be reviewedv_secPayload := bit2oct(encvalue(v_toBeSignedData));
// log("v_secPayload=", v_secPayload);
// Signed payload
if (ispresent(p_certificateName) and (valueof(p_certificateName) != cc_taCert_A)) {
if(not f_readSigningKey(valueof(p_certificateName), v_privateKey)){
return false;
}
} else {
if(not f_readSigningKey(cc_taCert_A, v_privateKey)){
return false;
}
}
v_signature := f_signWithEcdsaNistp256WithSha256(
v_secPayload,
v_privateKey
);*/