Newer
Older
* @author ETSI / STF481 / STF507 / STF517 / STF538
* @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.
import from LibCommon_BasicTypesAndValues all;
garciay
committed
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;
garciay
committed
// LibItsCommon
import from LibItsCommon_Functions all;
import from LibItsCommon_TypesAndValues all;
import from LibItsSecurity_TypesAndValues all;
garciay
committed
import from LibItsSecurity_Templates all;
import from LibItsSecurity_Pixits all;
import from LibItsSecurity_TestSystem all;
* @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(
) 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
* @param p_toBeSignedSecuredMessage The data to be signed
* @return The signature value
*/
function f_signWithEcdsaNistp256WithSha256(
in octetstring p_toBeSignedSecuredMessage,
in Oct32 p_privateKey
return fx_signWithEcdsaNistp256WithSha256(
} // End of function f_signWithEcdsaNistp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_privateKey The private key
* @return The signature value
*/
function f_signWithEcdsaBrainpoolp256WithSha256(
in octetstring p_toBeSignedSecuredMessage,
in Oct32 p_privateKey
return fx_signWithEcdsaBrainpoolp256WithSha256(
p_toBeSignedSecuredMessage,
p_privateKey
);
} // End of function f_signWithEcdsaBrainpoolp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @param p_toBeSignedSecuredMessage The data to be signed
* @param p_privateKey The private key
* @return The signature value
*/
function f_signWithEcdsaBrainpoolp384WithSha384(
in octetstring p_toBeSignedSecuredMessage,
in Oct48 p_privateKey
return fx_signWithEcdsaBrainpoolp384WithSha384(
p_toBeSignedSecuredMessage,
p_privateKey
);
} // End of function f_signWithEcdsaBrainpoolp384WithSha384
in octetstring p_encryptPrivateKey,
in EtsiTs103097Data p_encrypedSecuredMessage,
out EtsiTs103097Data p_decrypedSecuredMessage
) return boolean {
if (not(ischosen(p_encrypedSecuredMessage.content.encryptedData))) {
var PKRecipientInfo v_pKRecipientInfo;
var RecipientInfo v_recipientInfo := p_encrypedSecuredMessage.content.encryptedData.recipients[0];
// 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 {
return false;
}
if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256)) {
var octetstring v_decryptedSecuredMessage;
var SymmetricCiphertext v_ciphertext := p_encrypedSecuredMessage.content.encryptedData.ciphertext;
v_decryptedSecuredMessage := f_decryptWithEciesNistp256WithSha256(
v_pKRecipientInfo.encKey.eciesNistP256.v.uncompressedP256.x,
v_pKRecipientInfo.encKey.eciesNistP256.v.uncompressedP256.y,
v_pKRecipientInfo.encKey.eciesNistP256.c,
v_pKRecipientInfo.encKey.eciesNistP256.t,
v_ciphertext.aes128ccm.nonce
);
if (isbound(v_decryptedSecuredMessage)) {
var bitstring v_decode := oct2bit(v_decryptedSecuredMessage);
if (decvalue(v_decode, p_decrypedSecuredMessage) == 0) {
return true;
}
} else if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1)) {
var octetstring v_decryptedSecuredMessage;
var SymmetricCiphertext v_ciphertext := p_encrypedSecuredMessage.content.encryptedData.ciphertext;
v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256WithSha256(
v_ciphertext.aes128ccm.ccmCiphertext,
p_encryptPrivateKey,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.uncompressedP256.x,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.uncompressedP256.y,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.c,
v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.t,
v_ciphertext.aes128ccm.nonce
);
if (isbound(v_decryptedSecuredMessage)) {
var bitstring v_decode := oct2bit(v_decryptedSecuredMessage);
if (decvalue(v_decode, p_decrypedSecuredMessage) == 0) {
return true;
}
}
} // 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_recipientsPublicKeyX The Recipient's public encryption key X-coordinate
* @param p_recipientsPublicKeyY The Recipient's public encryption key Y-coordinate
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @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
*/
function f_encryptWithEciesNistp256WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyX,
in Oct32 p_recipientsPublicKeyY,
out Oct12 p_nonce
) return octetstring {
return fx_encryptWithEciesNistp256WithSha256(
p_recipientsPublicKeyX,
p_recipientsPublicKeyY,
p_publicEphemeralKeyX,
p_publicEphemeralKeyY,
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_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @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_publicEphemeralKeyX,
in Oct32 p_publicEphemeralKeyY,
in Oct16 p_encrypted_sym_key,
in Oct16 p_authentication_vector,
in Oct12 p_nonce
return fx_decryptWithEciesNistp256WithSha256(
p_encryptedSecuredMessage,
p_privateEncKey,
p_publicEphemeralKeyX,
p_publicEphemeralKeyY,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // End of function f_decryptWithEcdsaNistp256WithSha256
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
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) encryption using Brainpool-P256 algorithm
* @param p_toBeEncryptedSecuredMessage The data to be encrypted
* @param p_recipientsPublicKeyX The Recipient's public encryption key X-coordinate
* @param p_recipientsPublicKeyY The Recipient's public encryption key Y-coordinate
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @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_encryptWithEciesBrainpoolp256WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyX,
in Oct32 p_recipientsPublicKeyY,
out Oct32 p_publicEphemeralKeyX,
out Oct32 p_publicEphemeralKeyY,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce
) return octetstring {
return fx_encryptWithEciesBrainpoolp256WithSha256(
p_toBeEncryptedSecuredMessage,
p_recipientsPublicKeyX,
p_recipientsPublicKeyY,
p_publicEphemeralKeyX,
p_publicEphemeralKeyY,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // End of function f_encryptWithEciesBrainpoolp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Encrytion Algorithm (ECIES) decryption using Brainpool-P256 algorithm
* @param p_encryptedSecuredMessage The data to be decrypted
* @param p_publicEphemeralKeyX The generated ephemeral key X-coordinate
* @param p_publicEphemeralKeyY The generated ephemeral key Y-coordinate
* @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_decryptWithEciesBrainpoolp256WithSha256(
in octetstring p_encryptedSecuredMessage,
in Oct32 p_privateEncKey,
in Oct32 p_publicEphemeralKeyX,
in Oct32 p_publicEphemeralKeyY,
in Oct16 p_encrypted_sym_key,
in Oct16 p_authentication_vector,
in Oct12 p_nonce
) return octetstring {
return fx_decryptWithEciesBrainpoolp256WithSha256(
p_encryptedSecuredMessage,
p_privateEncKey,
p_publicEphemeralKeyX,
p_publicEphemeralKeyY,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // End of function f_decryptWithEcdsaBrainpoolp256WithSha256
* @desc Compute the HashedId8 value from the hash value
* @param p_hash The hash value
* @return The HashedId8 value
* @verdict
*/
) return HashedId8 {
return substr(p_hash, lengthof(p_hash) - 8, 8);
/**
* @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_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
*/
garciay
committed
function f_verifyWithEcdsaNistp256WithSha256(
in octetstring p_toBeVerifiedData,
in octetstring 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(
p_toBeVerifiedData,
p_signature,
p_ecdsaNistp256PublicKeyX,
p_ecdsaNistp256PublicKeyY);
} // End of function f_verifyWithEcdsaNistp256WithSha256
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @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_verifyWithEcdsaBrainpoolp256WithSha256(
in octetstring p_toBeVerifiedData,
in octetstring p_signature,
in Oct32 p_ecdsaBrainpoolp256PublicKeyX,
in Oct32 p_ecdsaBrainpoolp256PublicKeyY
) return boolean {
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: signature", p_signature);
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: ecdsaBrainpoolp256PublicKeyX", p_ecdsaBrainpoolp256PublicKeyX);
// log("f_verifyWithEcdsaBrainpoolp256WithSha256: ecdsaBrainpoolp256PublicKeyY", p_ecdsaBrainpoolp256PublicKeyY);
return fx_verifyWithEcdsaBrainpoolp256WithSha256(
p_toBeVerifiedData,
p_signature,
p_ecdsaBrainpoolp256PublicKeyX,
p_ecdsaBrainpoolp256PublicKeyY);
} // End of function f_verifyWithEcdsaBrainpoolp256WithSha256
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @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_verifyWithEcdsaBrainpoolp384WithSha384(
in octetstring p_toBeVerifiedData,
in octetstring p_signature,
in Oct48 p_ecdsaBrainpoolp384PublicKeyX,
in Oct48 p_ecdsaBrainpoolp384PublicKeyY
) return boolean {
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: toBeVerifiedData", p_toBeVerifiedData);
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: toBeVerifiedData length", lengthof(p_toBeVerifiedData));
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: signature", p_signature);
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: ecdsaBrainpoolp384PublicKeyX", p_ecdsaBrainpoolp384PublicKeyX);
// log("f_verifyWithEcdsaBrainpoolp384WithSha384: ecdsaBrainpoolp384PublicKeyY", p_ecdsaBrainpoolp384PublicKeyY);
return fx_verifyWithEcdsaBrainpoolp384WithSha384(
p_toBeVerifiedData,
p_signature,
p_ecdsaBrainpoolp384PublicKeyX,
p_ecdsaBrainpoolp384PublicKeyY);
} // End of function f_verifyWithEcdsaBrainpoolp384WithSha384
/**
* @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)
* @return true on success, false otherwise
*/
out Oct32 p_privateKey,
out Oct32 p_publicKeyX,
out Oct32 p_publicKeyY
) return boolean {
return fx_generateKeyPair_nistp256(p_privateKey, p_publicKeyX, p_publicKeyY);
}
/**
* @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)
* @return true on success, false otherwise
*/
function f_generate_key_pair_brainpoolp256(
out Oct32 p_privateKey,
out Oct32 p_publicKeyX,
out Oct32 p_publicKeyY
) return boolean {
return fx_generateKeyPair_brainpoolp256(p_privateKey, p_publicKeyX, p_publicKeyY);
}
/**
* @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)
* @return true on success, false otherwise
*/
function f_generate_key_pair_brainpoolp384(
out Oct48 p_privateKey,
out Oct48 p_publicKeyX,
out Oct48 p_publicKeyY
) return boolean {
return fx_generateKeyPair_brainpoolp384(p_privateKey, p_publicKeyX, p_publicKeyY);
/**
* @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;
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
* @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
) 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;
/**
* @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 {
// Load certificates if required
if (/*Spirent change*/lengthof(p_certificateName)>0 and (valueof(p_certificateName) != cc_taCert_A)) {
if (f_readCertificate(valueof(p_certificateName), p_atCertificate) == false){
if (f_readCertificate(oct2str(p_atCertificate.toBeSigned.cracaId), p_aaCertificate) == false) {
return false;
}
} else {
p_atCertificate := vc_atCertificate;
p_aaCertificate := vc_aaCertificate;
}
// Store the certificte 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(
out template (value) EtsiTs103097Data p_securedMessage,
in charstring p_certificateName,
in ToBeSignedData p_payloadField
) runs on ItsSecurityBaseComponent return boolean {
var octetstring v_secPayload, v_signature;
var Ieee1609Dot2Content v_toBeSignedPayload;
var Oct32 v_privateKey;
// Prepare payload to be signed
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
if (ispresent(p_certificateName) and (valueof(p_certificateName) != cc_taCert_A)) {
if(not f_readSigningKey(valueof(p_certificateName), v_privateKey)){
return false;
}
} else {
return false;
}
}
if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature)) {
v_signature := f_signWithEcdsaNistp256WithSha256(
v_secPayload,
v_privateKey
);
p_securedMessage.content.signedData.signature_ := 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_signWithEcdsaBrainpoolp256WithSha256(
v_secPayload,
v_privateKey
);
p_securedMessage.content.signedData.signature_ := m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(substr(v_signature, 0, 32)),
substr(v_signature, 32, 32)
)
);
} // TODO To be continued
} // 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(
in template (value) charstring p_certificateName,
in integer p_trailerStatus := 0,
in template (value) HeaderInfo p_mandatoryHeaders,
in template (omit) HeaderInfo p_headerInfo := omit
// 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
v_headerFields := valueof(p_mandatoryHeaders);
} else {/* FIXME To be reviewed
// Merge p_headerInfo and v_mandatoryHeaders into v_headerFields
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 (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);
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));
// 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 {
return false;
}
}
v_signature := f_signWithEcdsaNistp256WithSha256(
v_secPayload,
v_privateKey
/* FIXME To be reviewed if (p_trailerStatus == 0) { // No signature
p_payloadField,
{ }
);
v_trailerSize := 0;
} else if (p_trailerStatus == 2) { // Duplicate signature
p_payloadField,
{
m_trailer_field_signature(
m_signature(
m_ecdsaSignature(
m_eccPointecdsa_nistp256_with_sha256_y_coordinate_only(
substr(v_signature, 2, 32)
),
substr(v_signature, 34, 32)
)
)
),
m_trailer_field_signature(
m_signature(
m_ecdsaSignature(
m_eccPointecdsa_nistp256_with_sha256_y_coordinate_only(
substr(v_signature, 2, 32)
),
substr(v_signature, 34, 32)
)
)
)
}
);
} else if (p_trailerStatus == 3) { // Signature with reserved algorthm
p_securedMessage := m_ieee1609Dot2Data_wrong_protocol(
p_payloadField,
{
m_trailer_field_signature(
m_unknownSignature(
v_signature
)
)
}
);
} else { // Invalid signature
p_payloadField,
{
m_trailer_field_signature(
m_signature(
m_ecdsaSignature(
m_eccPointecdsa_nistp256_with_sha256_y_coordinate_only(
substr(v_signature, 2, 32)
),
substr(v_signature, 34, 32)
)
)
)
}
);
p_securedMessage.trailer_fields[0].trailerField.signature_.ecdsaNistP256Signature.sSig := not4b(valueof(p_securedMessage.trailer_fields[0].trailerField.signature_.ecdsaNistP256Signature.sSig));
}*/
return false;/* FIXME To be reviewed true;*/
} // End of function f_buildGnSecuredMessage_Bo
* @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_signerIdentifierType Add digest or AT certificate or certificate chain
* @param p_certificateName The certificate identifier to be used. Default: TA_CERT_A
* @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerInfo
* @see Draft ETSI TS 103 097 V1.1.14 Clause 7.1 Security profile for CAMs
out template (value) EtsiTs103097Data p_securedMessage,
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType,
in charstring p_certificateName := ""/*,
in boolean p_addMissingHeaders := true*/
) runs on ItsSecurityBaseComponent return boolean {
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
log("v_atCertificate = ", v_atCertificate);
// Fill sta structure with default values, these values will be updated later
p_securedMessage := m_etsiTs103097Data_signed(
m_signedData(
sha256,
p_payloadField,
m_signerIdentifier_self,
m_signature_ecdsaNistP256(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(int2oct(0, 32)),
int2oct(0, 32)
)
)
)
);
// Prepare mandatory headers
if (ischosen(p_signerIdentifierType.certificate)) { // Add the AT certificate
/* TODO
* v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificate(
v_atCertificate
)));
} else if (valueof(p_signerIdentifierType) == e_certificate_chain) { // Add the AT certificate + AA EtsiTs103097Certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificates(
{
v_aaCertificate,
}
)
));*/
} else if (ischosen(p_signerIdentifierType.digest)) { // Add the AT certificate digest
if (ischosen(v_atCertificate.issuer.sha256AndDigest)) {
p_securedMessage.content.signedData.hashId := sha256;
p_securedMessage.content.signedData.signer := m_signerIdentifier_digest(
f_calculateDigestSha256FromCertificate(v_atCertificate)
);
} else if (ischosen(v_atCertificate.issuer.sha384AndDigest)) {
p_securedMessage.content.signedData.hashId := sha384;
p_securedMessage.content.signedData.signer := m_signerIdentifier_digest(
f_calculateDigestSha384FromCertificate(v_atCertificate)
);
} else {
log("*** " & testcasename() & ": TODO ***");
stop;
}
if (ispresent(v_atCertificate.signature_)) {
if (ischosen(v_atCertificate.signature_.ecdsaBrainpoolP256r1Signature)) {
p_securedMessage.content.signedData.signature_ := m_signature_ecdsaBrainpoolP256r1(
m_ecdsaP256Signature(
m_eccP256CurvePoint_x_only(int2oct(0, 32)),
int2oct(0, 32)
)
);
} else if (ischosen(v_atCertificate.signature_.ecdsaBrainpoolP384r1Signature)) {
p_securedMessage.content.signedData.signature_ := m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(int2oct(0, 48)),
int2oct(0, 48)
)
);
} // else, m_signature_ecdsaNistP256 already chosen by default
}
log("p_securedMessage = ", p_securedMessage);
return f_buildGnSecuredMessage(p_securedMessage, p_certificateName, p_payloadField/*, v_mandatoryHeaders*/);
* @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_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_signerIdentifierType Add digest or AT certificate or certificate chain
* @param p_headerInfo HeaderInfo to be inserted in the message
* @param p_certificateName The certificate identifier to be used. Default: TA_CERT_A
* @param p_addMissingHeaders Whether to add mandatory headers not present in p_headerInfo
* @param p_alterATCertificateSignature Set to true to alter the AT certificate signature
* @param p_alterAACertificateSignature Set to true to alter the AA certificate signature
*
* @see Draft ETSI TS 103 097 V1.1.14 Clause 7.1 Security profile for CAMs
function f_buildGnSecuredCam_Bo(
in integer p_trailerStatus := 0,
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType, // FIXME To be reviewed
in template (omit) HeaderInfo p_headerInfo := omit,
in boolean p_addMissingHeaders := true,
in boolean p_alterATCertificateSignature := false,
in boolean p_alterAACertificateSignature := false
) runs on ItsSecurityBaseComponent return boolean {
// Local variables
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
var HeaderInfo v_mandatoryHeaders := {};
var HeaderInfo v_signerInfo;
// Load certificates if required
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
}
v_atCertificate.signature_.ecdsaNistP256Signature.sSig := not4b(v_atCertificate.signature_.ecdsaNistP256Signature.sSig);
v_aaCertificate.signature_.ecdsaNistP256Signature.sSig := not4b(v_aaCertificate.signature_.ecdsaNistP256Signature.sSig);
/* FIXME To be reviewed if (p_addMissingHeaders == true) {
// Prepare mandatory headers
if (valueof(p_signerIdentifierType) == e_certificate) { // Add the AT certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificate(
v_atCertificate
)));
} else if (valueof(p_signerIdentifierType) == e_certificate_chain) { // Add the AT certificate + AA EtsiTs103097Certificate
v_signerInfo := valueof(
m_header_info_signer_info(
m_signerIdentifier_certificates(
{
v_aaCertificate,