Newer
Older
* @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.
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 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
function f_signWithEcdsaNistp256WithSha256(
in octetstring p_toBeSignedSecuredMessage,
in Oct32 p_privateKey
return fx_signWithEcdsaNistp256WithSha256(
p_certificateIssuer,
} // 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_signWithEcdsaBrainpoolp256WithSha256(
in octetstring p_toBeSignedSecuredMessage,
return fx_signWithEcdsaBrainpoolp256WithSha256(
p_toBeSignedSecuredMessage,
p_certificateIssuer,
p_privateKey
);
} // End of function f_signWithEcdsaBrainpoolp256WithSha256
* @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_signWithEcdsaBrainpoolp384WithSha384(
in octetstring p_toBeSignedSecuredMessage,
return fx_signWithEcdsaBrainpoolp384WithSha384(
p_toBeSignedSecuredMessage,
p_certificateIssuer,
p_privateKey
);
} // End of function f_signWithEcdsaBrainpoolp384WithSha384
in octetstring p_encryptPrivateKey,
in EtsiTs103097Data p_encrypedSecuredMessage,
in octetstring p_salt,
out EtsiTs103097Data p_decrypedSecuredMessage,
out octetstring p_aes_sym_enc_key
if (ischosen(p_encrypedSecuredMessage.content.encryptedData)) {
var PKRecipientInfo v_pKRecipientInfo;
var RecipientInfo v_recipientInfo := p_encrypedSecuredMessage.content.encryptedData.recipients[0];
var octetstring v_decryptedSecuredMessage;
// 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 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 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,
p_salt, p_aes_sym_enc_key
);
} 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,
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 ***");
} // 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
*/
function f_encryptWithEciesNistp256WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyCompressed,
in octetstring p_salt,
out Oct32 p_publicEphemeralKeyCompressed,
out integer p_ephemeralKeyModeCompressed,
out Oct12 p_nonce,
in boolean p_use_hardcoded_values := false
return fx_encryptWithEciesNistp256WithSha256(
p_recipientsPublicKeyCompressed,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
p_encrypted_sym_key,
p_authentication_vector,
} // 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,
} // 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_encryptWithEciesBrainpoolp256WithSha256(
in octetstring p_toBeEncryptedSecuredMessage,
in Oct32 p_recipientsPublicKeyCompressed,
out Oct32 p_publicEphemeralKeyCompressed,
out integer p_ephemeralKeyModeCompressed,
out Oct16 p_encrypted_sym_key,
out Oct16 p_authentication_vector,
out Oct12 p_nonce,
in boolean p_use_hardcoded_values := false
) return octetstring {
return fx_encryptWithEciesBrainpoolp256WithSha256(
p_toBeEncryptedSecuredMessage,
p_recipientsPublicKeyCompressed,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
p_encrypted_sym_key,
p_authentication_vector,
p_nonce,
p_use_hardcoded_values
} // 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,
in Oct32 p_salt,
out Oct16 p_aes_sym_enc_key
) return octetstring {
return fx_decryptWithEciesBrainpoolp256WithSha256(
p_encryptedSecuredMessage,
p_privateEncKey,
p_publicEphemeralKeyCompressed,
p_ephemeralKeyModeCompressed,
p_encrypted_sym_key,
p_authentication_vector,
} // 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 whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @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
garciay
committed
function f_verifyWithEcdsaNistp256WithSha256(
in Oct32 p_certificateIssuer,
in Oct64 p_signature,
in Oct32 p_ecdsaNistp256PublicKeyCompressed,
) 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,
);
} // 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_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 whole-hash issuer certificate or int2oct(0, 32) in case of self signed certificate
* @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_verifyWithEcdsaBrainpoolp256WithSha256(
in octetstring p_toBeVerifiedData,
in Oct32 p_certificateIssuer,
in Oct64 p_signature,
in Oct32 p_ecdsaBrainpoolp256PublicKeyCompressed,
) 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,
);
} // 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 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_verifyWithEcdsaBrainpoolp256WithSha256_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_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 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_verifyWithEcdsaBrainpoolp384WithSha384(
in octetstring p_toBeVerifiedData,
in Oct48 p_certificateIssuer,
in Oct96 p_signature,
in Oct48 p_ecdsaBrainpoolp384PublicKeyCompressed,
) 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,
);
} // 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 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_verifyWithEcdsaBrainpoolp384WithSha384_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_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_compressed_mode 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,
if (PICS_SEC_FIXED_KEYS) { // Debug mode: Use fixed values
p_privateKey := '43481BC44C073C1432DB6EC4F0EF57062BEA08E4C19F811567325AD1FD1C6577'O;
p_publicKeyX := '0B5D74B033531C51D17B4F218DD4E39289AE4BF2EE3D7BAB7C07DAF0C14F0317'O;
p_publicKeyY := '5D49B139A9237832FDE24D77555878CE65D6C2284A1BDA4CE08ABDD4071E0255'O;
p_publicKeyCompressed := '0B5D74B033531C51D17B4F218DD4E39289AE4BF2EE3D7BAB7C07DAF0C14F0317'O;
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_brainpoolp256(
out Oct32 p_privateKey,
out Oct32 p_publicKeyX,
out Oct32 p_publicKeyY,
out Oct32 p_publicKeyCompressed,
log(">>> f_generate_key_pair_brainpoolp256");
return fx_generateKeyPair_brainpoolp256(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_brainpoolp384(
out Oct48 p_privateKey,
out Oct48 p_publicKeyX,
out Oct48 p_publicKeyY,
out Oct48 p_publicKeyCompressed,
return fx_generateKeyPair_brainpoolp384(p_privateKey, p_publicKeyX, p_publicKeyY, p_publicKeyCompressed, p_compressed_mode);
/**
* @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 {
//log(">>> f_prepareCertificates: ", p_certificateName);
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);
if (f_getCertificateFromDigest(v_digest, p_aaCertificate) == false) {
log("f_prepareCertificates: Failed to read certificate issuer ", v_digest);
return false;
}
} else {
p_atCertificate := vc_atCertificate;
p_aaCertificate := vc_aaCertificate;
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(
in charstring p_certificateName,
in ToBeSignedData p_payloadField
) runs on ItsSecurityBaseComponent return boolean {
var octetstring v_secPayload, v_signature;
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_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_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_signWithEcdsaBrainpoolp256WithSha256(
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_signWithEcdsaBrainpoolp384WithSha384(
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, 32)),
substr(v_signature, 32, 32)
)
));
log("<<< f_buildGnSecuredMessage: p_securedMessage=", p_securedMessage);
} // 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
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
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
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;
log(">>> f_buildGnSecuredCam: p_securedMessage= ", p_securedMessage);
log(">>> f_buildGnSecuredCam: p_payloadField= ", p_payloadField);
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
//log("f_buildGnSecuredCam: v_atCertificate = ", v_atCertificate);
// Fill the structure with default values, these values will be updated later
p_securedMessage := valueof(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)
)
)
)
//log("f_buildGnSecuredCam: p_signerIdentifierType=", p_signerIdentifierType);
if (ischosen(p_signerIdentifierType.certificate)) { // Add the AT certificate
log("*** " & testcasename() & "f_buildGnSecuredCam: TODO ***");
/* 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 := valueof(m_signerIdentifier_digest(
} else if (ischosen(v_atCertificate.issuer.sha384AndDigest)) {
p_securedMessage.content.signedData.hashId := sha384;
p_securedMessage.content.signedData.signer := valueof(m_signerIdentifier_digest(
log("*** " & testcasename() & "f_buildGnSecuredCam: TODO ***");
}
if (ispresent(v_atCertificate.signature_)) {
if (ischosen(v_atCertificate.signature_.ecdsaBrainpoolP256r1Signature)) {
p_securedMessage.content.signedData.signature_ := valueof(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_ := valueof(m_signature_ecdsaBrainpoolP384r1(
m_ecdsaP384Signature(
m_eccP384CurvePoint_x_only(int2oct(0, 48)),
int2oct(0, 48)
)
} // else, m_signature_ecdsaNistP256 already chosen by default
}
//log("f_buildGnSecuredCam: 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,
v_atCertificate
}
)
));
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
v_signerInfo := valueof(
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
f_calculateDigestFromCertificate(v_atCertificate)
)));
}
v_mandatoryHeaders := {
v_signerInfo,
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_its_aid(c_its_aid_CAM))
return f_buildGnSecuredMessage_Bo(p_securedMessage, p_certificateName, p_protocolVersion, p_trailerStatus, p_payloadField, v_mandatoryHeaders, p_headerInfo);
} // End of function f_buildGnSecuredCam_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_threeDLocation The 3D location
* @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
* @return true on success, false otherwise
*/
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType,
in template (omit) HeaderInfo p_headerInfo := omit,
) runs on ItsSecurityBaseComponent return boolean {
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
var HeaderInfo v_mandatoryHeaders := {};
var HeaderInfo v_signerInfo;
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
/* FIXME To be reviewed if (p_addMissingHeaders == true) {
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,
v_atCertificate
}
)
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
v_signerInfo := valueof(
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
v_atCertificate.cracaId
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_generation_location(p_threeDLocation)),
valueof(m_header_info_its_aid(c_its_aid_DENM))
// Build the secured message and return it
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_threeDLocation The 3D location
* @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
* @return true on success, false otherwise
*/
function f_buildGnSecuredDenm_Bo(
in integer p_trailerStatus := 0,
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType, // FIXME To be reviewed
in ThreeDLocation p_threeDLocation,
in template (omit) HeaderInfo p_headerInfo := omit,
in boolean p_addMissingHeaders := true
) 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;
}
// Add additional headers if required
/* 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,
v_atCertificate
}
)
));
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
v_signerInfo := valueof(
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
v_atCertificate.cracaId
)));
}
v_mandatoryHeaders := {
v_signerInfo,
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_generation_location(p_threeDLocation)),
valueof(m_header_info_its_aid(c_its_aid_DENM))
// Build the secured message and return it
return f_buildGnSecuredMessage_Bo(p_securedMessage, p_certificateName, p_protocolVersion, p_trailerStatus, p_payloadField, v_mandatoryHeaders, p_headerInfo);
} // End of function f_buildGnSecuredDenm_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_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
* @return true on success, false otherwise
*/
function f_buildGnSecuredOtherMessage(
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType, // FIXME To be reviewed
in template (omit) HeaderInfo p_headerInfo := omit,
) runs on ItsSecurityBaseComponent return boolean {
var EtsiTs103097Certificate v_aaCertificate, v_atCertificate;
var HeaderInfo v_mandatoryHeaders := {};
var HeaderInfo v_signerInfo;
if (f_prepareCertificates(p_certificateName, v_aaCertificate, v_atCertificate) == false) {
return false;
/* FIXME To be reviewed if (p_addMissingHeaders == true) {
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,
v_atCertificate
}
)
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
v_signerInfo := valueof(
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
v_atCertificate.cracaId
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_generation_location(p_threeDLocation))
// Build the secured message and return it
return f_buildGnSecuredMessage(p_securedMessage, p_certificateName, p_payloadField/*, v_mandatoryHeaders*/);
} // End of function f_buildGnSecuredOtherMessage
/**
* @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
* @return true on success, false otherwise
*/
function f_buildGnSecuredOtherMessage_Bo(
in ToBeSignedData p_payloadField,
in SignerIdentifier p_signerIdentifierType, // FIXME To be reviewed
in template (omit) HeaderInfo p_headerInfo := omit,
in boolean p_addMissingHeaders := true
) 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;
}
// Add additional headers if required
/* FIXME To be reviewed if (p_addMissingHeaders == true) {
if (valueof(p_signerIdentifierType) == e_certificate) { // Add the AT certificate
m_header_info_signer_info(
m_signerIdentifier_certificate(
} else if (valueof(p_signerIdentifierType) == e_certificate_chain) { // Add the AT certificate + AA EtsiTs103097Certificate
m_header_info_signer_info(
m_signerIdentifier_certificates(
{
v_aaCertificate,
v_atCertificate
}
)
));
} else if (valueof(p_signerIdentifierType) == e_certificate_digest_with_sha256) { // Add the AT certificate digest
m_header_info_signer_info(
m_issuerIdentifier_sha256AndDigest(
v_atCertificate.cracaId
)));
}
v_mandatoryHeaders := {
v_signerInfo,
valueof(m_header_info_generation_time(1000 * f_getCurrentTime())), // In us
valueof(m_header_info_generation_location(p_threeDLocation))
// FIXME To be done
// Build the secured message and return it
return f_buildGnSecuredMessage(p_securedMessage, p_certificateName, p_payloadField/*, v_mandatoryHeaders*/);
} // End of function f_buildGnSecuredOtherMessage_Bo
} // End of group hostSignatureHelpers
group deviceSignatureHelpers {
/**
* @desc Retrieve the HashedId8 to be sent to the IUT, based on the provided certificate identifier
* @param p_certificateName The certificate the IUT shall use
* @return The HashedId8 to be sent to the IUT in the UtInitialize command
* @verdict Unchanged
* @remark Component variable vc_hashedId8ToBeUsed shall be set with the IUT certificate to be used
*/
function f_setupIutCertificate(
in charstring p_certificateName
) runs on ItsSecurityBaseComponent return HashedId8 {
// Local variables
// var EtsiTs103097Certificate v_atCertificate;
var HashedId8 v_hashedId8 := '0000000000000000'O;
// Sanity check
if (lengthof(p_certificateName) == 0) {
return v_hashedId8;
}
// Load certificates
if(f_getCertificateDigest(p_certificateName, v_hashedId8) == false) {
v_hashedId8 := '0000000000000000'O;
}
return v_hashedId8;
} // End of function f_setupIutCertificate
* @desc Verify the signature of the provided certificate
* @param p_certificateToBeVerified EtsiTs103097Certificate to be verified
* @param p_publicKey Public key to verify the certificate signature
* @return true on success, false otherwise
* @verdict
*/
function f_verifyCertificateSignatureWithPublicKey(
in template (value) EtsiTs103097Certificate p_certificateToBeVerified,
in template (value) PublicVerificationKey p_publicVerificationKey
var ToBeSignedCertificate v_toBeSignedCertificate;
var octetstring v_enc_msg;
var octetstring v_signature;
log(">>> f_verifyCertificateSignatureWithPublicKey: p_certificateToBeVerified=", p_certificateToBeVerified);
log(">>> f_verifyCertificateSignatureWithPublicKey: p_publicVerificationKey=", p_publicVerificationKey);
// Create ToBeSignedCertificate payload to be signed
v_toBeSignedCertificate := valueof(p_certificateToBeVerified.toBeSigned);
log("f_verifyCertificateSignatureWithPublicKey: v_toBeSignedCertificate=", v_toBeSignedCertificate);
v_enc_msg := bit2oct(encvalue(v_toBeSignedCertificate));
log("f_verifyCertificateSignatureWithPublicKey: v_enc_msg=", v_enc_msg);
// Verify payload
if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP256r1)) {
if (ischosen(p_certificateToBeVerified.issuer.self_)) {
} else {
var charstring v_certificate;
if (fx_readCertificateFromDigest(valueof(p_certificateToBeVerified.issuer.sha256AndDigest), v_certificate) == false) {
log("f_verifyCertificateSignatureWithPublicKey: Invalid issuer: ", p_certificateToBeVerified.issuer.sha256AndDigest);
return false;
}
if (f_getCertificateHash(v_certificate, v_issuer) == false) {
log("f_verifyCertificateSignatureWithPublicKey: Invalid certificate: " & v_certificate);
return false;
}
}
v_signature := valueof(p_certificateToBeVerified.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only) & valueof(p_certificateToBeVerified.signature_.ecdsaBrainpoolP256r1Signature.sSig);
log("f_verifyCertificateSignatureWithPublicKey: v_signedData=", v_signature);
if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP256r1.uncompressedP256)) {
return f_verifyWithEcdsaBrainpoolp256WithSha256_1(
v_enc_msg,
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP256r1.uncompressedP256.x),
valueof(p_publicVerificationKey.ecdsaBrainpoolP256r1.uncompressedP256.y)
);
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP256r1.compressed_y_0)) {
return f_verifyWithEcdsaBrainpoolp256WithSha256(
v_enc_msg,
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP256r1.compressed_y_0),
0 // Latest bit of the Y-coordinate is 0
);
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP256r1.compressed_y_1)) {
return f_verifyWithEcdsaBrainpoolp256WithSha256(
v_enc_msg,
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP256r1.compressed_y_1),
1 // Latest bit of the Y-coordinate is 1
);
} else {
log("f_verifyCertificateSignatureWithPublicKey: Unknown PublicVerificationKey value");
return false;
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP384r1)) {
if (ischosen(p_certificateToBeVerified.issuer.self_)) {
} else {
var charstring v_certificate;
if (fx_readCertificateFromDigest(valueof(p_certificateToBeVerified.issuer.sha384AndDigest), v_certificate) == false) {
log("f_verifyCertificateSignatureWithPublicKey: Invalid issuer: ", p_certificateToBeVerified.issuer.sha384AndDigest);
return false;
}
if (f_getCertificateHash(v_certificate, v_issuer) == false) {
log("f_verifyCertificateSignatureWithPublicKey: Invalid certificate: " & v_certificate);
return false;
}
}
v_signature := valueof(p_certificateToBeVerified.signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only) & valueof(p_certificateToBeVerified.signature_.ecdsaBrainpoolP384r1Signature.sSig);
log("f_verifyCertificateSignatureWithPublicKey: v_signedData=", v_signature);
if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP384r1.uncompressedP384)) {
return f_verifyWithEcdsaBrainpoolp384WithSha384_1(
v_enc_msg,
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP384r1.uncompressedP384.x),
valueof(p_publicVerificationKey.ecdsaBrainpoolP384r1.uncompressedP384.y)
);
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP384r1.compressed_y_0)) {
return f_verifyWithEcdsaBrainpoolp384WithSha384(
v_enc_msg,
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP384r1.compressed_y_0),
0 // Latest bit of the Y-coordinate is 0
);
} else if (ischosen(p_publicVerificationKey.ecdsaBrainpoolP384r1.compressed_y_1)) {
return f_verifyWithEcdsaBrainpoolp384WithSha384(
v_enc_msg,
v_signature,
valueof(p_publicVerificationKey.ecdsaBrainpoolP384r1.compressed_y_1),
1 // Latest bit of the Y-coordinate is 1
);
} else {
log("f_verifyCertificateSignatureWithPublicKey: Unknown PublicVerificationKey value");
return false;
} else if (ischosen(p_publicVerificationKey.ecdsaNistP256)) {
if (ischosen(p_certificateToBeVerified.issuer.self_)) {
} else {
var charstring v_certificate;
if (fx_readCertificateFromDigest(valueof(p_certificateToBeVerified.issuer.sha256AndDigest), v_certificate) == false) {
log("f_verifyCertificateSignatureWithPublicKey: Invalid issuer: ", p_certificateToBeVerified.issuer.sha256AndDigest);
return false;
}
if (f_getCertificateHash(v_certificate, v_issuer) == false) {
log("f_verifyCertificateSignatureWithPublicKey: Invalid certificate: " & v_certificate);
return false;
}
}
v_signature := valueof(p_certificateToBeVerified.signature_.ecdsaNistP256Signature.rSig.x_only) & valueof(p_certificateToBeVerified.signature_.ecdsaNistP256Signature.sSig);
log("f_verifyCertificateSignatureWithPublicKey: v_signedData=", v_signature);
if (ischosen(p_publicVerificationKey.ecdsaNistP256.uncompressedP256)) {
return f_verifyWithEcdsaNistp256WithSha256_1(
v_enc_msg,
v_signature,
valueof(p_publicVerificationKey.ecdsaNistP256.uncompressedP256.x),
valueof(p_publicVerificationKey.ecdsaNistP256.uncompressedP256.y)
);
} else if (ischosen(p_publicVerificationKey.ecdsaNistP256.compressed_y_0)) {
return f_verifyWithEcdsaNistp256WithSha256(
v_signature,
valueof(p_publicVerificationKey.ecdsaNistP256.compressed_y_0),
0 // Latest bit of the Y-coordinate is 0
);
} else if (ischosen(p_publicVerificationKey.ecdsaNistP256.compressed_y_1)) {
return f_verifyWithEcdsaNistp256WithSha256(
v_signature,
valueof(p_publicVerificationKey.ecdsaNistP256.compressed_y_1),
1 // Latest bit of the Y-coordinate is 1
);
} else {
log("f_verifyCertificateSignatureWithPublicKey: Unknown PublicVerificationKey value");
return false;
} // End of finction f_verifyCertificateSignatureWithPublicKey
* @desc Verify the signature of the provided secured message
* @param p_certificateToBeVerified EtsiTs103097Certificate to be verified
* @param p_issuingCertificate Issuing certificate
* @return true on success, false otherwise
* @verdict
*/
function f_verifyCertificateSignatureWithIssuingCertificate(
in template (value) EtsiTs103097Certificate p_certificateToBeVerified,
in template (value) EtsiTs103097Certificate p_issuingCertificate
// Sanity checks
if (not(ischosen(p_issuingCertificate.toBeSigned.verifyKeyIndicator.verificationKey))) {
return false;
}
return f_verifyCertificateSignatureWithPublicKey(
p_certificateToBeVerified,
p_issuingCertificate.toBeSigned.verifyKeyIndicator.verificationKey
);
} // End of function f_verifyCertificateSignatureWithIssuingCertificate
* @desc Verify the signature of the provided secured message for ECDSA Nist-P256 algorithm
* @param p_securedMessage The message to be verified
* @param p_publicKey The ECDSA public key to verify a signature
* @param p_certificate EtsiTs103097Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_verifyGnSecuredMessageSignature_ecdsaNistP256(
in template (value) Ieee1609Dot2Data p_securedMessage,
in template (value) Oct32 p_certificateIssuer,
in template (value) EccP256CurvePoint p_publicKey
) return boolean {
// Local variables
var octetstring v_secPayload;
var octetstring v_signedData;
var boolean v_result := false;
var template (value) ToBeSignedData v_toBeSignedData;
log(">>> f_verifyGnSecuredMessageSignature_ecdsaNistP256: p_securedMessage= ", p_securedMessage);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaNistP256: p_certificateIssuer= ", p_certificateIssuer);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaNistP256: p_publicKey= ", p_publicKey);
// Create Ieee1609Dot2Data payload to be signed
v_toBeSignedData := valueof(p_securedMessage.content.signedData.tbsData);
log("f_verifyGnSecuredMessageSignature_ecdsaNistP256: v_toBeSignedData=", p_securedMessage.content.signedData.tbsData);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
log("f_verifyGnSecuredMessageSignature_ecdsaNistP256: v_secPayload=", v_secPayload);
// Verify payload
// TODO Check in standard if x-only only
if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.rSig.x_only)) {
v_signedData := valueof(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.rSig.x_only) & valueof(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.sSig);
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.rSig.compressed_y_0)) {
v_signedData := valueof(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.rSig.compressed_y_0) & valueof(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.sSig);
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.rSig.compressed_y_1)) {
v_signedData := valueof(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.rSig.compressed_y_1) & valueof(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature.sSig);
}
log("f_verifyGnSecuredMessageSignature_ecdsaNistP256: v_signedData=", v_signedData);
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
if (ischosen(p_publicKey.uncompressedP256)) {
v_result := f_verifyWithEcdsaNistp256WithSha256_1(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.uncompressedP256.x),
valueof(p_publicKey.uncompressedP256.y)
);
} else if (ischosen(p_publicKey.compressed_y_0)) {
v_result := f_verifyWithEcdsaNistp256WithSha256(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_0),
0
);
} else if (ischosen(p_publicKey.compressed_y_1)) {
v_result := f_verifyWithEcdsaNistp256WithSha256(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_1),
1
);
}
log("f_verifyGnSecuredMessageSignature_ecdsaNistP256: v_result=", v_result);
return v_result;
} // End of function f_verifyGnSecuredMessageSignature_ecdsaNistP256
/**
* @desc Verify the signature of the provided secured message for ECDSA Brainpool-P256 algorithm
* @param p_securedMessage The message to be verified
* @param p_publicKey The ECDSA public key to verify a signature
* @param p_certificate EtsiTs103097Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1(
in template (value) Ieee1609Dot2Data p_securedMessage,
in template (value) Oct32 p_certificateIssuer,
in template (value) EccP256CurvePoint p_publicKey
) return boolean {
// Local variables
var octetstring v_secPayload;
var octetstring v_signedData;
var boolean v_result := false;
var template (value) ToBeSignedData v_toBeSignedData;
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: p_securedMessage= ", p_securedMessage);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: p_certificateIssuer= ", p_certificateIssuer);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: p_publicKey= ", p_publicKey);
// Create Ieee1609Dot2Data payload to be signed
v_toBeSignedData := valueof(p_securedMessage.content.signedData.tbsData);
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: v_toBeSignedData=", p_securedMessage.content.signedData.tbsData);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: v_secPayload=", v_secPayload);
// Verify payload
v_signedData := valueof(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.rSig.x_only) & valueof(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP256r1Signature.sSig);
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: v_signedData=", v_signedData);
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
if (ischosen(p_publicKey.uncompressedP256)) {
v_result := f_verifyWithEcdsaBrainpoolp256WithSha256_1(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.uncompressedP256.x),
valueof(p_publicKey.uncompressedP256.y)
);
} else if (ischosen(p_publicKey.compressed_y_0)) {
v_result := f_verifyWithEcdsaBrainpoolp256WithSha256(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_0),
0
);
} else if (ischosen(p_publicKey.compressed_y_1)) {
v_result := f_verifyWithEcdsaBrainpoolp256WithSha256(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_1),
1
);
}
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1: v_result=", v_result);
return v_result;
} // End of function f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1
/**
* @desc Verify the signature of the provided secured message for ECDSA Brainpool-P384 algorithm
* @param p_securedMessage The message to be verified
* @param p_publicKey The ECDSA public key to verify a signature
* @param p_certificate EtsiTs103097Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1(
in template (value) Ieee1609Dot2Data p_securedMessage,
in template (value) Oct48 p_certificateIssuer,
in template (value) EccP384CurvePoint p_publicKey
) return boolean {
// Local variables
var octetstring v_secPayload;
var octetstring v_signedData;
var boolean v_result := false;
var template (value) ToBeSignedData v_toBeSignedData;
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: p_securedMessage= ", p_securedMessage);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: p_certificateIssuer= ", p_certificateIssuer);
log(">>> f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: p_publicKey= ", p_publicKey);
// Create Ieee1609Dot2Data payload to be signed
v_toBeSignedData := valueof(p_securedMessage.content.signedData.tbsData);
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: v_toBeSignedData=", p_securedMessage.content.signedData.tbsData);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: v_secPayload=", v_secPayload);
v_signedData := valueof(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.rSig.x_only) & valueof(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP384r1Signature.sSig);
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: v_signedData=", v_signedData);
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
if (ischosen(p_publicKey.uncompressedP384)) {
v_result := f_verifyWithEcdsaBrainpoolp384WithSha384_1(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.uncompressedP384.x),
valueof(p_publicKey.uncompressedP384.y)
);
} else if (ischosen(p_publicKey.compressed_y_0)) {
v_result := f_verifyWithEcdsaBrainpoolp384WithSha384(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_0),
0
);
} else if (ischosen(p_publicKey.compressed_y_1)) {
v_result := f_verifyWithEcdsaBrainpoolp384WithSha384(
v_secPayload,
valueof(p_certificateIssuer),
v_signedData,
valueof(p_publicKey.compressed_y_1),
1
);
}
log("f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1: v_result=", v_result);
} // End of function f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1
* @desc Verify the signature of the provided secured message
* @param p_securedMessage
* @param p_certificate EtsiTs103097Certificate to be used to verify the message
* @return true on success, false otherwise
* @verdict
*/
function f_verifyGnSecuredMessageSignatureWithCertificate(
in template (value) Ieee1609Dot2Data p_securedMessage,
in template (value) charstring p_certificate_id,
in template (value) EtsiTs103097Certificate p_certificate
var EtsiTs103097Certificate v_certificate;
log(">>> f_verifyGnSecuredMessageSignatureWithCertificate: p_securedMessage=", p_securedMessage);
log(">>> f_verifyGnSecuredMessageSignatureWithCertificate: p_certificate_id=", p_certificate_id);
log(">>> f_verifyGnSecuredMessageSignatureWithCertificate: p_certificate=", p_certificate);
if (f_getCertificateHash(valueof(p_certificate_id), v_issuer) == false) {
log("f_verifyCertificateSignatureWithPublicKey: Invalid certificate id: " & valueof(p_certificate_id));
if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP256r1Signature)) {
return f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP256r1(p_securedMessage, v_issuer, p_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP256r1);
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaBrainpoolP384r1Signature)) {
return f_verifyGnSecuredMessageSignature_ecdsaBrainpoolP384r1(p_securedMessage, v_issuer, p_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaBrainpoolP384r1);
} else if (ischosen(p_securedMessage.content.signedData.signature_.ecdsaNistP256Signature)) {
return f_verifyGnSecuredMessageSignature_ecdsaNistP256(p_securedMessage, v_issuer, p_certificate.toBeSigned.verifyKeyIndicator.verificationKey.ecdsaNistP256);
} // End of function f_verifyGnSecuredOtherMessageWithDeviceCertificate
} // End of group deviceSignatureHelpers
garciay
committed
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
group sspPermissions {
function f_verifySspPermissions(
in SequenceOfPsidSsp p_issuer_ssp_permissions,
in SequenceOfPsidSsp p_subordinate_ssp_permissions
) return boolean {
// Local variables
var integer v_idx := 0;
for (v_idx := 0; v_idx < lengthof(p_issuer_ssp_permissions); v_idx := v_idx + 1) {
var PsidSsp v_issuerPsidSsp := p_issuer_ssp_permissions[v_idx];
var PsidSsp v_subordinatePsidSsp;
var boolean v_found := false;
var integer v_jdx := 0;
// 1. Check permission from issuer is present
for (v_jdx := 0; v_jdx < lengthof(p_subordinate_ssp_permissions); v_jdx := v_jdx + 1) {
if (match(v_issuerPsidSsp, m_appPermissions(p_subordinate_ssp_permissions[v_jdx].psid, p_subordinate_ssp_permissions[v_jdx].ssp)) == true) {
v_subordinatePsidSsp := p_subordinate_ssp_permissions[v_jdx];
v_found := true;
break;
}
} // End of 'for' statement
if (v_found == false) {
log("f_verifySspPermissions: Permission set not found: ", v_issuerPsidSsp)
return false;
}
// 2. Validate bits mask
if (ispresent(v_issuerPsidSsp.ssp)) {
if (ispresent(v_subordinatePsidSsp.ssp) == false) {
log("f_verifySspPermissions: Ssp shall not be omitted: ", v_issuerPsidSsp)
return false;
}
if ((ischosen(v_issuerPsidSsp.ssp.bitmapSsp) == false) or (ischosen(v_subordinatePsidSsp.ssp.bitmapSsp) == false)) {
log("f_verifySspPermissions: Wrong variant : ", v_issuerPsidSsp.ssp, " / ", v_subordinatePsidSsp.ssp);
return false;
}
if (lengthof(v_issuerPsidSsp.ssp.bitmapSsp) < lengthof(v_subordinatePsidSsp.ssp.bitmapSsp)) {
log("f_verifySspPermissions: Ssp not be compliant: ", v_issuerPsidSsp.ssp, " / ", v_subordinatePsidSsp.ssp);
return false;
} else {
var charstring v_issuerSsp := bit2str(oct2bit(v_issuerPsidSsp.ssp.bitmapSsp));
var charstring v_subordinateSsp := bit2str(oct2bit(v_subordinatePsidSsp.ssp.bitmapSsp));
for (var integer i := 0; i < lengthof(v_issuerSsp); i := i + 1) {
if (v_issuerSsp[i] == "1") { // TODO How to check Permission using SspBitmask/SspValue
if (v_subordinateSsp[i] != "1") {
log("f_verifySspPermissions: Ssp bitmask mismatch at index: ", i);
return false;
}
} // else, no restriction, subordinate certificate can have any value.
} // End of 'for' statement
}
}
} // End of 'for' statement
return true;
} // End of function f_verifySspPermissions
} // End of group sspPermissions
* @desc return Ieee1609Dot2Data header field of given type or null if none
* @param p_msg the Ieee1609Dot2Data
* @return HeaderInfo of given type if any or null
in template(omit) Ieee1609Dot2Data p_securedMessage,
out HeaderInfo p_return
) return boolean {
if (not isvalue(p_securedMessage)) {
testcase.stop(__SCOPE__ & " can not handle omitted secured message values");
}
v_securedMessage := valueof(p_securedMessage);
if (ispresent(v_securedMessage.content.signedData)) {
p_return := v_securedMessage.content.signedData.tbsData.headerInfo;
return true;
}
}
/**
* @desc return SignerIdentifier Ieee1609Dot2Data field
in template(omit) Ieee1609Dot2Data p_securedMessage,
out SignerIdentifier p_signerIdentifier
) return boolean {
if (not isvalue(p_securedMessage)) {
testcase.stop(__SCOPE__ & " can not handle omitted secured message values");
}
if (ischosen(p_securedMessage.content.signedData)) {
p_signerIdentifier := valueof(p_securedMessage.content.signedData.signer);
return true;
}
log("f_getMsgSignerIdentifier: return false");
* @desc Set the generation location as defined in Draft ETSI TS 103 097 V1.1.14 Clause 7.2 Security profile for DENMs
* @param p_latitude The latitude value of the ITS-S position
* @param p_longitude The longitude value of the ITS-S position
* @param p_elevation The elevation value of the ITS-S position
* @verdict Unchanged
*/
function f_setGenerationLocation(
in SecLatitude p_latitude,
in SecLongitude p_longitude,
in SecElevation p_elevation := 0
) runs on ItsSecurityBaseComponent {
vc_location := {
p_elevation
}
} // End of function f_setGenerationLocation
* @desc Load in memory cache the certificates available
* @param p_configId A configuration identifier
* @remark This method SHALL be call before any usage of certificates
* @return true on success, false otherwise
*/
) runs on ItsSecurityBaseComponent return boolean {
// Setup certificates memory cache
if (fx_loadCertificates(PX_CERTIFICATE_POOL_PATH, p_configId) == true) {
// Setup security component variables
if (f_readCertificate(cc_taCert_A, vc_atCertificate) == true) {
var HashedId8 v_issuer;
log("Issuer: ", vc_atCertificate.issuer);
if (ischosen(vc_atCertificate.issuer.sha256AndDigest)) {
v_issuer := vc_atCertificate.issuer.sha256AndDigest;
} else if (ischosen(vc_atCertificate.issuer.sha384AndDigest)) {
v_issuer := vc_atCertificate.issuer.sha384AndDigest;
} else {
log("AT certificate cannot be issued by CA");
return false;
}
log("Selected issuer: ", v_issuer);
if (f_getCertificateFromDigest(v_issuer, vc_aaCertificate)) {
if (f_readSigningKey(cc_taCert_A, vc_signingPrivateKey) == true) {
f_readEncryptingKey(cc_taCert_A, vc_encryptPrivateKey);
return true;
}
log("f_loadCertificates: Failed to load signing key for ", cc_taCert_A);
} else {
log("f_loadCertificates: Failed to load AA certificate for ", cc_taCert_A);
}
} else {
log("f_loadCertificates: Failed to load AT certificate for ", cc_taCert_A);
}
log("f_loadCertificates: Failed to load certificates from ", PX_CERTIFICATE_POOL_PATH);
return false;
} // End of function f_loadCertificates
/**
* @desc Unload from memory cache the certificates available
* @return true on success, false otherwise
*/
function f_unloadCertificates() runs on ItsSecurityBaseComponent return boolean {
// Reset security component variables
vc_signingPrivateKey := ''O;
vc_encryptPrivateKey := ''O;
// Clear certificates memory cache
return fx_unloadCertificates();
} // End of function f_unloadCertificates
* @desc Read the specified certificate
* @param p_certificate_id the certificate identifier
* @param p_certificate the expected certificate
* @return true on success, false otherwise
*/
) return boolean {
var octetstring v_certificate;
if (fx_readCertificate(p_certificate_id, v_certificate) == true) {
var bitstring v_oct2bit;
var integer v_result;
v_oct2bit := oct2bit(v_certificate);
v_result := decvalue(v_oct2bit, p_certificate);
if (v_result == 0) {
return true;
}
}
log("f_readCertificate: Failed to retrieve ", p_certificate_id);
} // End of function f_readCertificate
* @desc Read the specified certificate
* @param p_certificate_id the certificate identifier
* @param p_digest the digest of the certificate
* @return true on success, false otherwise
*/
function f_getCertificateDigest(
) return boolean {
if (not fx_readCertificateDigest(p_certificate_id, p_digest)){
log("f_getCertificateDigest: Failed to retrieve digest for ", p_certificate_id);
return false;
}
return true;
} // End of function f_getCertificateDigest
/**
* @desc Read the whole-hash of the certificate
* @param p_certificate_id the certificate identifier
* @param p_hash the whole-hash of the certificate
* @return true on success, false otherwise
*/
function f_getCertificateHash(
out octetstring p_hash
) return boolean {
if (not fx_readCertificateHash(p_certificate_id, p_hash)){
log("f_getCertificateHash: Failed to retrieve digest for ", p_certificate_id);
return false;
}
return true;
} // End of function f_getCertificateHash
function f_getCertificateFromDigest(
in HashedId8 p_digest,
out EtsiTs103097Certificate p_certificate
) return boolean {
var charstring v_certificate_id;
if (not(fx_readCertificateFromDigest(p_digest, v_certificate_id))) {
log("f_getCertificateFromDigest: Failed to retrieve digest for ", p_digest);
return false;
}
if (not(f_readCertificate(v_certificate_id, p_certificate))) {
log("f_getCertificateFromDigest: Failed to retrieve digest for ", v_certificate_id);
return false;
}
return true;
} // End of function f_getCertificateFromDigest
function f_getCertificateFromHashedId3(
in HashedId3 p_digest,
out EtsiTs103097Certificate p_certificate
) return boolean {
var charstring v_certificate_id;
if (not(fx_readCertificateFromHashedId3(p_digest, v_certificate_id))) {
log("f_getCertificateFromHashedId3: Failed to retrieve digest for ", p_digest);
return false;
}
if (not(f_readCertificate(v_certificate_id, p_certificate))) {
log("f_getCertificateFromHashedId3: Failed to retrieve digest for ", v_certificate_id);
return false;
}
return true;
} // End of function f_getCertificateFromHashedId3
* @desc Read the signing private key for the specified certificate
* @param p_keysId the keys identifier
* @param p_signingPrivateKey the signing private key
* @return true on success, false otherwise
*/
function f_readSigningKey(
in charstring p_keysId,
out Oct32 p_signingPrivateKey
) return boolean {
return fx_readSigningKey(p_keysId, p_signingPrivateKey);
} // End of function f_readSigningKey
/**
* @desc Read the encrypting private keys for the specified certificate
* @param p_keysId the keys identifier
* @param p_encryptPrivateKey the encrypt private key
* @return true on success, false otherwise
*/
function f_readEncryptingKey(
) return boolean {
return fx_readEncryptingKey(p_keysId, p_encryptPrivateKey);
} // End of function f_readEncryptingKey
function f_getCertificateValidityRestriction(
in template (value) EtsiTs103097Certificate p_cert,
out template (value) ValidityPeriod p_validityPeriod,
out template (omit) GeographicRegion p_geographicRegion
) return boolean {
p_validityPeriod := valueof(p_cert.toBeSigned.validityPeriod);
if (ispresent(p_cert.toBeSigned.region)) {
p_geographicRegion := valueof(p_cert.toBeSigned.region);
} else {
p_geographicRegion := omit;
}
} // End of function f_getCertificateValidityRestriction
group certificatesCaching {
function f_createCertificatesCaching(
out CertificatesCaching p_certificatesCaching
) return boolean {
p_certificatesCaching := { };
for (var integer v_counter := 0; v_counter < lengthof(p_certificates); v_counter := v_counter + 1) {
var CertificatesCachingItem v_item;
v_item.certificate := p_certificates[v_counter];
v_item.hashedId8 := f_calculateDigestSha256FromCertificate(v_item.certificate);
p_certificatesCaching[v_counter] := v_item;
} // End of 'for' statement
return true;
}
function f_getCertificateFromCaching(
in CertificatesCaching p_certificatesCaching,
in HashedId8 p_hashedId8,
) return boolean {
for (var integer v_counter := 0; v_counter < lengthof(p_certificatesCaching); v_counter := v_counter + 1) {
if (match(p_certificatesCaching[v_counter].hashedId8, p_hashedId8) == true) {
p_certificate := p_certificatesCaching[v_counter].certificate;
return true;
}
} // End of 'for' statement
return false;
}
function f_getCertificatesCachingItem(
in CertificatesCaching p_certificatesCaching,
in UInt8 p_index,
) return boolean {
if (lengthof(p_certificatesCaching) < p_index) {
p_certificate := p_certificatesCaching[p_index].certificate;
return true;
}
return false;
}
function f_getCertificatesCachingItemSize(
in CertificatesCaching p_certificatesCaching
) return UInt8 {
return lengthof(p_certificatesCaching);
}
}// End of group certificatesCaching
} // End of 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
*/
external function fx_hashWithSha256(in octetstring p_toBeHashedData) return Oct32;
* @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
*/
external function fx_hashWithSha384(in octetstring p_toBeHashedData) return Oct48;
external function fx_hmac_sha256(in octetstring p_k, in octetstring p_m) return octetstring;
* @desc This function validates AES128 CCM encryption based on IEEE Std 1609.2-20XX Annex D.6.1 AES-CCM-128
* @param[in] The symmetric AES 128 encryption key
* @param[in] The initial vector (aka nonce)
* @param[in] The raw payload
* @return The encrypted payload
external function fx_encrypt_aes_128_ccm_test(in octetstring p_k, in octetstring p_n, in octetstring p_pt) return octetstring;
* @desc TThis function validates AES128 CCM encryption based on AES-GCM-256
* @param[in] The symmetric AES 128 encryption key
* @param[in] The initial vector (aka nonce)
* @param[in] The raw payload
* @return The encrypted payload
external function fx_encrypt_aes_128_gcm_test(in octetstring p_k, in octetstring p_n, in octetstring p_pt) return octetstring;
* @desc This function validates AES128 CCM decryption based on IEEE Std 1609.2-20XX Annex D.6.1 AES-CCM-128
* @param[in] The symmetric AES 128 encryption key
* @param[in] The initial vector (aka nonce)
* @param[in] The cyphered payload
* @return The raw payload
external function fx_decrypt_aes_128_ccm_test(in octetstring p_k, in octetstring p_n, in octetstring p_pt) return octetstring;
* @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
* @return The encrypted message
external function fx_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, in boolean p_use_hardcoded_values := false) return octetstring;
external function fx_test_encryptWithEciesNistp256WithSha256(in octetstring p_toBeEncryptedSecuredMessage, in Oct32 p_privateEphemeralKey, in Oct32 p_recipientPublicKeyX, in Oct32 p_recipientPublicKeyY, in octetstring p_salt, out Oct32 p_publicEphemeralKeyX, out Oct32 p_publicEphemeralKeyY, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce) return octetstring;
* @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
external function fx_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;
/**
* @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
*/
external function fx_encryptWithEciesBrainpoolp256WithSha256(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, in boolean p_use_hardcoded_values := false) return octetstring;
external function fx_test_encryptWithEciesBrainpoolp256WithSha256(in octetstring p_toBeEncryptedSecuredMessage, in Oct32 p_privateEphemeralKey, in Oct32 p_recipientPublicKeyX, in Oct32 p_recipientPublicKeyY, in octetstring p_salt, out Oct32 p_publicEphemeralKeyX, out Oct32 p_publicEphemeralKeyY, out Oct16 p_aes_sym_key, out Oct16 p_encrypted_sym_key, out Oct16 p_authentication_vector, out Oct12 p_nonce) return octetstring;
/**
* @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
*/
external function fx_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, in Oct32 p_salt, out Oct16 p_aes_sym_enc_key) return octetstring;
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @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
* @return The signature value
*/
external function fx_signWithEcdsaNistp256WithSha256(in octetstring p_toBeSignedSecuredMessage, in Oct32 p_certificateIssuer, in Oct32 p_privateKey) return octetstring;
external function fx_test_signWithEcdsaNistp256WithSha256(in octetstring p_toBeSignedSecuredMessage, in Oct32 p_privateKey) return octetstring;
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @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
external function fx_signWithEcdsaBrainpoolp256WithSha256(in octetstring p_toBeSignedSecuredMessage, in Oct32 p_certificateIssuer, in Oct32 p_privateKey) return octetstring;
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signature
* @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
external function fx_signWithEcdsaBrainpoolp384WithSha384(in octetstring p_toBeSignedSecuredMessage, in Oct48 p_certificateIssuer, in Oct48 p_privateKey) return octetstring;
/**
* @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
*/
external function fx_verifyWithEcdsaNistp256WithSha256(in octetstring p_toBeVerifiedData, in Oct32 p_certificateIssuer, in octetstring p_signature, in Oct32 p_ecdsaNistp256PublicKeyCompressed, in integer p_compressed_mode) return boolean;
external function fx_test_verifyWithEcdsaNistp256WithSha256(in octetstring p_toBeVerifiedData, in octetstring p_signature, in Oct32 p_ecdsaNistp256PublicKeyCompressed, in integer p_compressed_mode) return boolean;
* @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
*/
external function fx_verifyWithEcdsaNistp256WithSha256_1(in octetstring p_toBeVerifiedData, in Oct32 p_certificateIssuer, in Oct64 p_signature, in Oct32 p_ecdsaNistp256PublicKeyX, in Oct32 p_ecdsaNistp256PublicKeyY) return boolean;
/**
* @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
*/
external function fx_verifyWithEcdsaBrainpoolp256WithSha256(in octetstring p_toBeVerifiedData, in Oct32 p_certificateIssuer, in Oct64 p_signature, in Oct32 p_ecdsaBrainpoolp256PublicKeyCompressed, in integer p_compressed_mode) return boolean;
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The 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
*/
external function fx_verifyWithEcdsaBrainpoolp256WithSha256_1(in octetstring p_toBeVerifiedData, in Oct32 p_certificateIssuer, in Oct64 p_signature, in Oct32 p_ecdsaBrainpoolp256PublicKeyX, in Oct32 p_ecdsaBrainpoolp256PublicKeyY) return boolean;
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_certificateIssuer The certificate issuer
* @param p_signature The signature
* @param p_ecdsaBrainpoolp384PublicKeyCompressed 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
*/
external function fx_verifyWithEcdsaBrainpoolp384WithSha384(in octetstring p_toBeVerifiedData, in Oct48 p_certificateIssuer, in Oct96 p_signature, in Oct48 p_ecdsaBrainpoolp384PublicKeyCompressed, in integer p_compressed_mode) return boolean;
/**
* @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_ecdsaBrainpoolp384PublicKeyX The public key (x coordinate)
* @param p_ecdsaBrainpoolp384PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
external function fx_verifyWithEcdsaBrainpoolp384WithSha384_1(in octetstring p_toBeVerifiedData, in Oct48 p_certificateIssuer, in Oct96 p_signature, in Oct48 p_ecdsaBrainpoolp384PublicKeyX, in Oct48 p_ecdsaBrainpoolp384PublicKeyY) return boolean;
* @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
external function fx_generateKeyPair_nistp256(out Oct32 p_privateKey, out Oct32 p_publicKeyX, out Oct32 p_publicKeyY, out Oct32 p_publicKeyCompressed, out integer p_compressed_mode) return boolean;
/**
* @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
*/
external function fx_generateKeyPair_brainpoolp256(out Oct32 p_privateKey, out Oct32 p_publicKeyX, out Oct32 p_publicKeyY, out Oct32 p_publicKeyCompressed, out integer p_compressed_mode) return boolean;
/**
* @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
*/
external function fx_generateKeyPair_brainpoolp384(out Oct48 p_privateKey, out Oct48 p_publicKeyX, out Oct48 p_publicKeyY, out Oct48 p_publicKeyCompressed, out integer p_compressed_mode) return boolean;
group encryption {
} // End of group encryption
group certificatesLoader {
/**
* @desc Load in memory cache the certificates available in the specified directory
* @param p_rootDirectory Root directory to access to the certificates identified by the certificate ID
* @param p_configId A configuration identifier
* @remark This method SHALL be call before any usage of certificates
* @return true on success, false otherwise
*/
external function fx_loadCertificates(in charstring p_rootDirectory, in charstring p_configId) return boolean;
external function fx_store_certificate(in charstring p_cert_id, in octetstring p_cert, in octetstring p_private_key, in octetstring p_public_key_x, in octetstring p_public_key_y, in octetstring p_public_key_compressed, in integer p_public_key_compressed_mode, in octetstring p_hash, in octetstring p_hashid8, in octetstring p_issuer, in template (omit) octetstring p_private_enc_key, in template (omit) octetstring p_public_enc_key_x, in template (omit) octetstring p_public_enc_key_y, in template (omit) octetstring p_public_enc_compressed_key, in template (omit) integer p_public_enc_key_compressed_mode) return boolean;
* @desc Unload from memory cache the certificates
* @return true on success, false otherwise
*/
external function fx_unloadCertificates() return boolean;
* @desc Read the specified certificate
* @param p_certificate_id the certificate identifier
* @param p_certificate the expected certificate
* @return true on success, false otherwise
*/
external function fx_readCertificate(in charstring p_certificate_id, out octetstring p_certificate) return boolean;
* @desc Read the specified certificate digest
* @param p_certificate_id the certificate identifier
* @param p_digest the expected certificate
* @return true on success, false otherwise
*/
external function fx_readCertificateDigest(in charstring p_certificate_id, out HashedId8 p_digest) return boolean;
/**
* @desc Read the whole-hash of the specified certificate
* @param p_certificate_id the certificate identifier
* @param p_hash the whole-hash of the certificate
* @return true on success, false otherwise
*/
external function fx_readCertificateHash(in charstring p_certificate_id, out octetstring p_hash) return boolean;
external function fx_readCertificateFromDigest(in HashedId8 p_digest, out charstring p_certificate_id) return boolean;
external function fx_readCertificateFromHashedId3(in HashedId3 p_digest, out charstring p_certificate_id) return boolean;
* @desc Read the private keys for the specified certificate
* @param p_keysId the keys identifier
* @param p_signingPrivateKey the signing private key
* @return true on success, false otherwise
*/
external function fx_readSigningKey(in charstring p_keysId, out Oct32 p_signingPrivateKey) return boolean;
/**
* @desc Read the private keys for the specified certificate
* @param p_keysId the keys identifier
* @param p_encryptPrivateKey the encrypt private key
* @return true on success, false otherwise
*/
external function fx_readEncryptingKey(in charstring p_keysId, out Oct32 p_encryptingPrivateKey) return boolean;
} // End of group certificatesLoader
* @desc Check that given polygon doesn't have neither self-intersections nor holes.
* @param p_region Polygonal Region
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isValidPolygonalRegion(in PolygonalRegion p_region) return boolean;
* @desc Check if a polygonal region is inside another one
* @param p_parent The main polygonal region
* @param p_region The polygonal region to be included
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isPolygonalRegionInside(in PolygonalRegion p_parent, in PolygonalRegion p_region) return boolean;
* @desc Check that the location is inside a circular region
* @param p_region The circular region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isLocationInsideCircularRegion(in CircularRegion p_region, in ThreeDLocation p_location) return boolean;
* @desc Check that the location is inside a rectangular region
* @param p_region The rectangular region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isLocationInsideRectangularRegion(in SequenceOfRectangularRegion p_region, in ThreeDLocation p_location) return boolean;
* @desc Check that the location is inside a polygonal region
* @param p_region The polygonal region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isLocationInsidePolygonalRegion(in PolygonalRegion p_region, in ThreeDLocation p_location) return boolean;
* @desc Check if the location is inside an identified region
* @param p_region The identified region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isLocationInsideIdentifiedRegion(in IdentifiedRegion p_region, in ThreeDLocation p_location) return boolean;
/**
* @desc Check if the location is inside an undefined region
* @param p_region The identified region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
external function fx_isLocationInsideOtherRegion(in octetstring p_region, in ThreeDLocation p_location) return boolean;
/**
* @desc Check that p_circular_region_1 circular region is included into p_circular_region_2 circular region
* @param p_circular_region_1 Circular region 1
* @param p_circular_region_2 Circular region 2
*
* @return true on success, false otherwise
*/
external function fx_areCirclesInside(in CircularRegion p_circular_region_1, in CircularRegion p_circular_region_2) return boolean;
/**
* @desc Check that p_rectanglar_region_1 rectangular region is included into p_rectanglar_region_2 rectangular region
* @param p_rectanglar_region_1 Rectangular region 1
* @param p_rectanglar_region_2 Rectangular region 2
*
* @return true on success, false otherwise
*/
external function fx_areRectanglesInside(in SequenceOfRectangularRegion p_rectanglar_region_1, in SequenceOfRectangularRegion p_rectanglar_region_2) return boolean;
/**
* @desc Check that p_polygonal_region_1 polygonal region is included into p_polygonal_region_2 polygonal region
* @param p_polygonal_region_1 Polygonal region 1
* @param p_polygonal_region_2 Polygonal region 2
*
* @return true on success, false otherwise
*/
external function fx_arePolygonsInside(in PolygonalRegion p_polygonal_region_1, in PolygonalRegion p_polygonal_region_2) return boolean;
* @desc Convert a spacial coordinate from DMS to Dms
* @param p_degrees The degrees (D)
* @param p_minutes The minutes (M)
* @param p_seconds The seconds (S)
* @param p_latlon The latitude/longitude: (N|S|E|W)
* @return The decimal coordinate on success, 0.0, otherwise
* @verdict Unchanged
*/
external function fx_dms2dd(in Int p_degrees, in Int p_minutes, in float p_seconds, in Oct1 p_latlon) return float;
} // End of group externalFunctions
in EtsiTs103097Certificate p_cert,
in EtsiTs103097Certificate p_cert_issuer
var ValidityPeriod v_cert_region, v_cert_issuer_region;
/* FIXME To be reviewed v_cert_issuer_region_result := f_getCertificateValidityRestriction(p_cert_issuer, e_region, v_cert_issuer_region);
if (f_getCertificateValidityRestriction(p_cert, e_region, v_cert_region) == false) {
if (v_cert_issuer_region_result == true) {
if (v_cert_issuer_region.validity.region.region_type != e_none) {
return false;
}
}
} else if (
(v_cert_issuer_region_result == true) and
(v_cert_issuer_region.validity.region.region_type != e_none)
if (v_cert_region.validity.region.region_type == e_circle) {
if (v_cert_issuer_region.validity.region.region_type == e_circle) {
// Check v_cert_region 'circle' is inside v_cert_issuer_region 'circle'
if (f_areCirclesInside(v_cert_region.validity.region.region.circular_region, v_cert_issuer_region.validity.region.region.circular_region) == false) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing certificates circle area does not match ***");
return false;
}
}
} else if (v_cert_region.validity.region.region_type == e_rectangle) {
if (v_cert_issuer_region.validity.region.region_type == e_rectangle) {
// Check v_cert_region 'rectangle' is inside v_cert_issuer_region 'rectangle'
if (f_areRectanglesInside(v_cert_region.validity.region.region.rectangular_region, v_cert_issuer_region.validity.region.region.rectangular_region) == false) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing certificates rectangle area does not match ***");
return false;
}
}
} else if (v_cert_region.validity.region.region_type == e_polygon) {
if (v_cert_issuer_region.validity.region.region_type == e_polygon) {
// Check v_cert_region 'polygon' is inside v_cert_issuer_region 'polygon'
if (f_arePolygonsInside(v_cert_region.validity.region.region.polygonal_region, v_cert_issuer_region.validity.region.region.polygonal_region) == false) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing certificates polygon area does not match ***");
return false;
}
}
} else if (v_cert_region.validity.region.region_type == e_id) {
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
// Check id_region
if (not match (v_cert_region.validity.region, mw_geographicRegion_identified(mw_identifiedRegion_iso3166_any))) {
log("*** " & testcasename() & ": FAIL: Identified region is not conformed to ISO 3166-1 ***");
return false;
}
if (not match (v_cert_region.validity.region, mw_geographicRegion_identified(mw_identifiedRegion_un_stats_any))) {
log("*** " & testcasename() & ": FAIL: Identified region is not conformed to United Nations Statistics Division ***");
return false;
}
// Check region_dictionary
if (not match (v_cert_region.validity.region.region.id_region.region_dictionary, v_cert_issuer_region.validity.region.region.id_region.region_dictionary)) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing 'region_dictionary' field does not match ***");
return false;
}
// Check region_identifier
if (not match (v_cert_region.validity.region.region.id_region.region_identifier, v_cert_issuer_region.validity.region.region.id_region.region_identifier)) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing 'region_identifier' field does not match ***");
return false;
}
// Check local_region
if (
(not match (v_cert_issuer_region.validity.region.region.id_region.local_region, v_cert_region.validity.region.region.id_region.local_region)) or
(not match (v_cert_issuer_region.validity.region.region.id_region.local_region, 0))
) {
log("*** " & testcasename() & ": FAIL: Issuer and issuing 'local_region' field does not match ***");
return true;
} // End of function f_checkRegionValidityRestiction
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
* @desc Check that p_circular_region_1 circular region is included into p_circular_region_2 circular region
* @param p_circular_region_1 Circular region 1
* @param p_circular_region_2 Circular region 2
*
* @return true on success, false otherwise
*/
function f_areCirclesInside(
in CircularRegion p_circular_region_1,
in CircularRegion p_circular_region_2
) return boolean {
return fx_areCirclesInside(p_circular_region_1, p_circular_region_2);
}
/**
* @desc Check that p_rectanglar_region_1 rectangular region is included into p_rectanglar_region_2 rectangular region
* @param p_rectanglar_region_1 Rectangular region 1
* @param p_rectanglar_region_2 Rectangular region 2
*
* @return true on success, false otherwise
*/
function f_areRectanglesInside(
in SequenceOfRectangularRegion p_rectanglar_region_1,
in SequenceOfRectangularRegion p_rectanglar_region_2
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
) return boolean {
return fx_areRectanglesInside(p_rectanglar_region_1, p_rectanglar_region_2);
}
/**
* @desc Check that p_polygonal_region_1 polygonal region is included into p_polygonal_region_2 polygonal region
* @param p_polygonal_region_1 Polygonal region 1
* @param p_polygonal_region_2 Polygonal region 2
*
* @return true on success, false otherwise
*/
function f_arePolygonsInside(
in PolygonalRegion p_polygonal_region_1,
in PolygonalRegion p_polygonal_region_2
) return boolean {
return fx_arePolygonsInside(p_polygonal_region_1, p_polygonal_region_2);
}
/**
* @desc Check that given location is valid
* @param p_location location to be checked
* @return true on success, false otherwise
*/
//FIXME RGY Titan doesn't support dot notation after valueof at the moment
// (valueof(p_location).longitude != c_maxLongitude + 1) and
// (valueof(p_location).latitude != c_maxLatitude + 1);
(valueof(p_location.longitude) != c_maxLongitude + 1) and
(valueof(p_location.latitude) != c_maxLatitude + 1);
} // End of function f_isValidTwoDLocation
* @desc Check that two given rectanlular regions are intersected
* Note: Regions must be normalized(northWest.latitude >= southEast.latitude)
* @param p_r1 Region 1
* @param p_r2 Region 2
*
* @return true on success, false otherwise
*/
function f_isRectangularRegionsIntersected(
in template (value) RectangularRegion p_r1,
in template (value) RectangularRegion p_r2
//FIXME RGY Titan doesn't support dot notation after valueof at the moment
// valueof(p_r2).northWest.longitude > valueof(p_r1).southEast.longitude or
// valueof(p_r2).southEast.longitude < valueof(p_r1).northWest.longitude or
// valueof(p_r2).southEast.latitude > valueof(p_r1).northWest.latitude or
// valueof(p_r2).northWest.latitude < valueof(p_r1).southEast.latitude
valueof(p_r2.northWest.longitude) > valueof(p_r1.southEast.longitude) or
valueof(p_r2.southEast.longitude) < valueof(p_r1.northWest.longitude) or
valueof(p_r2.southEast.latitude) > valueof(p_r1.northWest.latitude) or
valueof(p_r2.northWest.latitude) < valueof(p_r1.southEast.latitude)
} // End of function f_isRectangularRegionsIntersected
in template (value) SequenceOfRectangularRegion p_region
var integer v_i, v_j;
var boolean v_found;
for (v_i := 0; v_i < lengthof(p_region); v_i := v_i + 1) {
var PolygonalRegion v_region_base;
f_convertRectangularRegionIntoPolygonalRegion(valueof(p_region[v_i]), v_region_base);
v_found := false;
for (v_j := 0; v_j < lengthof(p_region); v_j := v_j + 1) {
if (v_j != v_i) {
var PolygonalRegion v_region;
f_convertRectangularRegionIntoPolygonalRegion(valueof(p_region[v_j]), v_region);
if (f_isPolygonalRegionInside(v_region, v_region_base) == true) {
v_found := true;
}
}
} // End of 'for' statement
if (v_found == false) {
return false;
}
} // End of 'for' statement
} // End of function f_isContinuousRectangularRegions
* @desc Check if a polygonal region is inside another one
* @param p_parent The main polygonal region
* @param p_region The polygonal region to be included
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isRectangularRegionsInside(
in template (value) SequenceOfRectangularRegion p_parent,
in template (value) SequenceOfRectangularRegion p_region
var integer v_i, v_j;
for (v_i := 0; v_i < lengthof(p_parent); v_i := v_i + 1) {
var PolygonalRegion v_region_parent, v_region;
f_convertRectangularRegionIntoPolygonalRegion(valueof(p_parent[v_i]), v_region_parent);
for (v_j := 0; v_j < lengthof(p_parent); v_j := v_j + 1) {
f_convertRectangularRegionIntoPolygonalRegion(valueof(p_region[v_j]), v_region);
if (f_isPolygonalRegionInside(v_region, v_region_parent) == true) {
return true;
}
} // End of 'for' statement
} // End of 'for' statement
return false;
} // End of function f_isRectangularRegionsInside
/**
* @desc Convert a rectangular region into a polygonal region
* @param p_region The rectangular regions to convert
* @return
* @verdict
*/
function f_convertRectangularRegionIntoPolygonalRegion(
in template (value) RectangularRegion p_rectangular_region,
out PolygonalRegion p_region
) return boolean {
// Convert rectangular regions to polygons and check polygons
p_region[0] := valueof(p_rectangular_region.northWest);
p_region[1] := {
valueof(p_rectangular_region.northWest.latitude) + valueof(p_rectangular_region.southEast.latitude),
valueof(p_rectangular_region.northWest.longitude)
};
p_region[2] := valueof(p_rectangular_region.southEast);
p_region[3] := {
valueof(p_rectangular_region.northWest.latitude),
valueof(p_rectangular_region.northWest.longitude) + valueof(p_rectangular_region.southEast.longitude)
};
log("f_convertRectangularRegionIntoPolygonalRegion: DEBUG: Northwest location is invalid in rect ", p_region);
return true;
} // End of function
* @desc Check that given polygon doesn't have neither self-intersections nor holes.
* @param p_region Polygonal Region
* @return true on success, false otherwise
* @verdict Unchanged
*/
// Sanity check
if (not isbound(p_region) or (lengthof(p_region) == 0)) {
return false;
}
return fx_isValidPolygonalRegion(valueof(p_region));
} // End of function f_isValidPolygonalRegion
* @desc Check if a polygonal region is inside another one
* @param p_parent The main polygonal region
* @param p_region The polygonal region to be included
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isPolygonalRegionInside(
in template (value) PolygonalRegion p_parent,
in template (value) PolygonalRegion p_region
// Sanity check
if (not isbound(p_parent) or not isbound(p_region) or (lengthof(p_parent) == 0) or (lengthof(p_region) == 0)) {
return false;
}
return fx_isPolygonalRegionInside(valueof(p_parent), valueof(p_region));
} // End of function f_isPolygonalRegionInside
function f_isIdentifiedRegionInside(
in template (value) UInt16 p_parent,
in template (value) UInt16 p_region
} // End of function f_isIdentifiedRegionInside
* @desc Check that the location is inside a region
* @param p_region The region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsideRegion(
in template (value) GeographicRegion p_region,
in template (value) ThreeDLocation p_location
) return boolean {
var boolean v_ret := false;
if (ischosen(p_region.circularRegion)) {
v_ret := f_isLocationInsideCircularRegion(valueof(p_region.circularRegion), p_location);
} else if (ischosen(p_region.rectangularRegion)) {
v_ret := f_isLocationInsideRectangularRegion(valueof(p_region.rectangularRegion), p_location);
} else if (ischosen(p_region.polygonalRegion)) {
v_ret := f_isLocationInsidePolygonalRegion(valueof(p_region.polygonalRegion), p_location);
} else if (ischosen(p_region.identifiedRegion)) {
for (var integer v_i := 0; v_i < lengthof(p_region.identifiedRegion); v_i := v_i + 1) {
if (f_isLocationInsideIdentifiedRegion(valueof(p_region.identifiedRegion[v_i]), p_location) == true) {
v_ret := true;
break;
}
} // End of 'for' statement
} // End of function f_isLocationInsideRegion
/**
* @desc Check that the location is inside a circular region
* @param p_region The circular region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsideCircularRegion(
in template (value) CircularRegion p_region,
in template (value) ThreeDLocation p_location
// Sanity check
if (not isbound(p_region) or not isbound(p_location)) {
return false;
}
return fx_isLocationInsideCircularRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsideCircularRegion
/**
* @desc Check that the location is inside a rectangular region
* @param p_region The rectangular region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsideRectangularRegion(
in template (value) SequenceOfRectangularRegion p_region,
// Sanity check
if (not isbound(p_region) or not isbound(p_location) or (lengthof(p_region) == 0)) {
return false;
}
// log("f_isLocationInsideRectangularRegion: p_polygonalArea: ", p_region);
// log("f_isLocationInsideRectangularRegion: p_location: ", p_location);
return fx_isLocationInsideRectangularRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsideRectangularRegion
/**
* @desc Check that the location is inside a polygonal region
* @param p_region The polygonal region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsidePolygonalRegion(
in template (value) PolygonalRegion p_region,
in template (value) ThreeDLocation p_location
// Sanity check
if (not isbound(p_region) or not isbound(p_location) or (lengthof(p_region) == 0)) {
return false;
}
// log("f_isLocationInsidePolygonalRegion: p_polygonalArea: ", p_region, " - ", valueof(p_region));
// log("f_isLocationInsidePolygonalRegion: p_location: ", p_location, " - ", valueof(p_location));
return fx_isLocationInsidePolygonalRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsidePolygonalRegion
/**
* @desc Check if the location is inside an identified region
* @param p_region The identified region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsideIdentifiedRegion(
in template (value) IdentifiedRegion p_region,
in template (value) ThreeDLocation p_location
// Sanity check
if (not isbound(p_region) or not isbound(p_location)) {
return false;
}
return fx_isLocationInsideIdentifiedRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsideIdentifiedRegion
/**
* @desc Check if the location is inside an undefined region
* @param p_region The identified region to consider
* @param p_location The device location
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_isLocationInsideOtherRegion(
in template (value) octetstring p_region,
in template (value) ThreeDLocation p_location
// Sanity check
if (valueof(p_region) == ''O) {
return false;
}
return fx_isLocationInsideOtherRegion(valueof(p_region), valueof(p_location));
} // End of function f_isLocationInsideOtherRegion
* @desc Convert a spacial coordinate from DMS to Dms
* @param p_degrees The degrees (D)
* @param p_minutes The minutes (M)
* @param p_seconds The seconds (S)
* @param p_latlon The latitude/longitude: (N|S|E|W)
* @return The decimal coordinate on success, 0.0, otherwise
* @verdict Unchanged
*/
in integer p_degrees,
in integer p_minutes,
in float p_seconds,
in charstring p_latlon
// Sanity checks
if (lengthof(p_latlon) != 1) {
return 0.0;
} else if ((p_latlon != "N") and (p_latlon != "S") and (p_latlon != "E") and (p_latlon != "W")) {
return 0.0;
}
return fx_dms2dd(p_degrees, p_minutes, p_seconds, v_latlon);
} // End of function f_dms2dd
/**
* @desc Convert the latitude from float to int
* @param p_latitude The latitude to be converted. Significand length shall be 7 digits length
* @return The converted latitude
* @verdict Unchanged
*/
return float2int(p_latitude * 10000000.0); // Significand length shall be 7 digits length
}
/**
* @desc Convert the longitude from float to int
* @param p_longitude The longitude to be converted. Significand length shall be 6 digits length
* @return The converted longitude
* @verdict Unchanged
*/
return float2int(p_longitude * 1000000.0); // Significand length shall be 6 digits length
}
} // End of module LibItsSecurity_Functions