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 (Hash ( Hash (Data input) || Hash (Signer identifier input) ))
* @param p_certificateIssuer The hash of the canonical certificate issuer
* @param p_privateKey The private key for signature
function f_signWithEcdsaNistp256WithSha256(
in octetstring p_toBeSignedSecuredMessage,
in Oct32 p_certificateIssuer,
in Oct32 p_privateKey
return fx_signWithEcdsaNistp256WithSha256(
p_certificateIssuer,
} // End of function f_signWithEcdsaNistp256WithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @param p_toBeSignedSecuredMessage The data to be signed (Hash ( Hash (Data input) || Hash (Signer identifier input) ))
* @param p_certificateIssuer The hash of the canonical certificate issuer
* @param p_privateKey The private key for signature
* @return The signature value
*/
function f_signWithEcdsaBrainpoolp256WithSha256(
in octetstring p_toBeSignedSecuredMessage,
in Oct32 p_certificateIssuer,
return fx_signWithEcdsaBrainpoolp256WithSha256(
p_toBeSignedSecuredMessage,
p_certificateIssuer,
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 (Hash ( Hash (Data input) || Hash (Signer identifier input) ))
* @param p_certificateIssuer The hash of the canonical certificate issuer
* @param p_privateKey The private key for signature
* @return The signature value
*/
function f_signWithEcdsaBrainpoolp384WithSha384(
in octetstring p_toBeSignedSecuredMessage,
in Oct48 p_certificateIssuer,
return fx_signWithEcdsaBrainpoolp384WithSha384(
p_toBeSignedSecuredMessage,
p_certificateIssuer,
p_privateKey
);
} // End of function f_signWithEcdsaBrainpoolp384WithSha384
in octetstring p_encryptPrivateKey,
in EtsiTs103097Data p_encrypedSecuredMessage,
out EtsiTs103097Data p_decrypedSecuredMessage
) return boolean {
if (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
log("*** " & testcasename() & ":ERROR: Unsupported RecipientInfo variant ***");
return false;
if (ischosen(v_pKRecipientInfo.encKey.eciesNistP256)) {
var octetstring v_decryptedSecuredMessage;
var SymmetricCiphertext v_ciphertext := p_encrypedSecuredMessage.content.encryptedData.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
);
} 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
);
} 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 octetstring v_decryptedSecuredMessage;
var SymmetricCiphertext v_ciphertext := p_encrypedSecuredMessage.content.encryptedData.ciphertext;
if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_0)) {
v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256WithSha256(
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
);
} else if (ischosen(v_pKRecipientInfo.encKey.eciesBrainpoolP256r1.v.compressed_y_1)) {
v_decryptedSecuredMessage := f_decryptWithEciesBrainpoolp256WithSha256(
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
);
} 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 {
log("*** " & testcasename() & ":ERROR: Message not encrypted ***");
} // 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_compressedMode 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
*/
function f_encryptWithEciesNistp256WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyCompressed,
in integer p_compressedMode,
out Oct32 p_publicEphemeralKeyCompressed,
out integer p_ephemeralKeyModeCompressed,
out Oct12 p_nonce
) return octetstring {
return fx_encryptWithEciesNistp256WithSha256(
p_recipientsPublicKeyCompressed,
p_compressedMode,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
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_publicEphemeralKeyCompressed,
in integer p_ephemeralKeyModeCompressed,
in Oct16 p_encrypted_sym_key,
in Oct16 p_authentication_vector,
in Oct12 p_nonce
return fx_decryptWithEciesNistp256WithSha256(
p_encryptedSecuredMessage,
p_privateEncKey,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce
);
} // 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_compressedMode 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_encryptWithEciesBrainpoolp256WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyX,
in integer p_compressedMode,
out Oct32 p_publicEphemeralKeyCompressed,
out integer p_ephemeralKeyModeCompressed,
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_compressedMode,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
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_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_decryptWithEciesBrainpoolp256WithSha256(
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
) return octetstring {
return fx_decryptWithEciesBrainpoolp256WithSha256(
p_encryptedSecuredMessage,
p_privateEncKey,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
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_certificateIssuer The hash of the canonical certificate issuer
* @param p_ecdsaNistp256PublicKeyCompressed The compressed public key
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
garciay
committed
function f_verifyWithEcdsaNistp256WithSha256(
in Oct32 p_certificateIssuer,
in Oct32 p_ecdsaNistp256PublicKeyCompressed,
in integer p_compressedMode
) 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_compressedMode
);
} // 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 hash of the canonical certificate issuer
* @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 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_1(
p_certificateIssuer,
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 hash of the canonical certificate issuer
* @param p_ecdsaBrainpoolp256PublicKeyCompressed The compressed public key
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp256WithSha256(
in octetstring p_toBeVerifiedData,
in Oct32 p_certificateIssuer,
in Oct32 p_ecdsaBrainpoolp256PublicKeyCompressed,
in integer p_compressedMode
) 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: ecdsaBrainpoolp256PublicKeyCompressed", p_ecdsaBrainpoolp256PublicKeyCompressed);
return fx_verifyWithEcdsaBrainpoolp256WithSha256(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp256PublicKeyCompressed,
p_compressedMode
);
} // End of function f_verifyWithEcdsaBrainpoolp256WithSha256
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The hash of the canonical certificate issuer
* @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_1( // TODO To be removed
in octetstring p_toBeVerifiedData,
in Oct32 p_certificateIssuer,
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_1(
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp256PublicKeyX,
p_ecdsaBrainpoolp256PublicKeyY);
} // End of function f_verifyWithEcdsaBrainpoolp256WithSha256_1
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The hash of the canonical certificate issuer
* @param p_signature The signature
* @param p_ecdsaBrainpoolp384PublicKeyX The public key (x coordinate)
* @param p_ecdsaBrainpoolp384PublicKeyY The public key (y coordinate)
* @param p_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
function f_verifyWithEcdsaBrainpoolp384WithSha384(
in octetstring p_toBeVerifiedData,
in Oct48 p_certificateIssuer,
in Oct48 p_ecdsaBrainpoolp384PublicKeyCompressed,
in integer p_compressedMode
) 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: ecdsaBrainpoolp384PublicKeyCompressed", p_ecdsaBrainpoolp384PublicKeyCompressed);
return fx_verifyWithEcdsaBrainpoolp384WithSha384(
p_toBeVerifiedData,
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp384PublicKeyCompressed,
p_compressedMode
);
} // End of function f_verifyWithEcdsaBrainpoolp384WithSha384
/**
* @Desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The hash of the canonical certificate issuer
* @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_1( // TODO To be removed
in octetstring p_toBeVerifiedData,
in Oct48 p_certificateIssuer,
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_1(
p_certificateIssuer,
p_signature,
p_ecdsaBrainpoolp384PublicKeyX,
p_ecdsaBrainpoolp384PublicKeyY);
} // End of function f_verifyWithEcdsaBrainpoolp384WithSha384_1
/**
* @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_compressedMode The compressed mode, 0 if the latest bit of Y-coordinate is 0, 1 otherwise
* @return true on success, false otherwise
*/
out Oct32 p_privateKey,
out Oct32 p_publicKeyX,
out Oct32 p_publicKeyY,
out Oct32 p_publicKeyCompressed,
out integer p_compressedMode
return fx_generateKeyPair_nistp256(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressedMode);
}
/**
* @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_compressedMode 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_brainpoolp256(
out Oct32 p_privateKey,
out Oct32 p_publicKeyX,
out Oct32 p_publicKeyY,
out Oct32 p_publicKeyCompressed,
out integer p_compressedMode
return fx_generateKeyPair_brainpoolp256(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressedMode);
}
/**
* @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_compressedMode 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_brainpoolp384(
out Oct48 p_privateKey,
out Oct48 p_publicKeyX,
out Oct48 p_publicKeyY,
out Oct48 p_publicKeyCompressed,
out integer p_compressedMode
return fx_generateKeyPair_brainpoolp384(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressedMode);
/**
* @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 octetstring v_certificateHash;
var octetstring 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;
}
}
f_getCertificateHash(p_certificateName, v_certificateHash);
if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature)) {
v_signature := f_signWithEcdsaNistp256WithSha256(
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_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)
)
);
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) {
v_signature := f_signWithEcdsaBrainpoolp384WithSha384(
v_secPayload,
v_certificateHash,
v_privateKey
);
p_securedMessage.content.signedData.signature_ := m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(substr(v_signature, 0, 32)),
substr(v_signature, 32, 32)
)
);
} // 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) {