module ItsGenCert_Functions { // 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; // LibItsSecurity import from LibItsSecurity_EncdecDeclarations all; import from LibItsSecurity_TypesAndValues all; import from LibItsSecurity_Templates all; import from LibItsSecurity_Functions all; import from LibItsSecurity_Pixits all; // AtsGenCert import from ItsGenCert_TypeAndValues all; import from ItsGenCert_Templates all; import from ItsGenCert_Pics all; function f_generate_signing_keys( in certificate_params p_certificate_params, inout certificate_details p_certificate_details ) return integer { if (p_certificate_params.curve == e_nist_p256) { f_generate_key_pair_nistp256(p_certificate_details.private_key, p_certificate_details.public_key_x, p_certificate_details.public_key_y, p_certificate_details.public_key_compressed, p_certificate_details.public_key_compressed_mode); } else if (p_certificate_params.curve == e_brainpool_p256) { f_generate_key_pair_brainpoolp256(p_certificate_details.private_key, p_certificate_details.public_key_x, p_certificate_details.public_key_y, p_certificate_details.public_key_compressed, p_certificate_details.public_key_compressed_mode); } else if (p_certificate_params.curve == e_brainpool_p384) { f_generate_key_pair_brainpoolp384(p_certificate_details.private_key, p_certificate_details.public_key_x, p_certificate_details.public_key_y, p_certificate_details.public_key_compressed, p_certificate_details.public_key_compressed_mode); } else { log("f_generate_signing_keys: Unsupported curve"); return -1; } if (p_certificate_params.encryption_key == true) { if (p_certificate_params.encryption_curve == e_nist_p256) { f_generate_key_pair_nistp256(p_certificate_details.private_enc_key, p_certificate_details.public_enc_key_x, p_certificate_details.public_enc_key_y, p_certificate_details.public_key_compressed, p_certificate_details.public_key_compressed_mode); } else if (p_certificate_params.encryption_curve == e_brainpool_p256) { f_generate_key_pair_brainpoolp256(p_certificate_details.private_enc_key, p_certificate_details.public_enc_key_x, p_certificate_details.public_enc_key_y, p_certificate_details.public_key_compressed, p_certificate_details.public_key_compressed_mode); } else { log("f_generate_signing_keys: Unsupported encryption curve"); return -1; } } return 0; } // End of function f_generate_signing_keys function f_fill_certificate( in certificate_params p_certificate_params, inout certificate_details p_certificate_details ) return integer { var VerificationKeyIndicator v_publicVerificationKey; if (p_certificate_params.curve == e_nist_p256) { if (p_certificate_details.public_key_compressed_mode == 0) { v_publicVerificationKey := valueof( m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaNistP256( m_eccP256CurvePoint_compressed_y_0( p_certificate_details.public_key_compressed )))); } else { v_publicVerificationKey := valueof( m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaNistP256( m_eccP256CurvePoint_compressed_y_1( p_certificate_details.public_key_compressed )))); } } else if (p_certificate_params.curve == e_brainpool_p256) { if (p_certificate_details.public_key_compressed_mode == 0) { v_publicVerificationKey := valueof( m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaBrainpoolP256r1( m_eccP256CurvePoint_compressed_y_0( p_certificate_details.public_key_compressed )))); } else { v_publicVerificationKey := valueof( m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaBrainpoolP256r1( m_eccP256CurvePoint_compressed_y_1( p_certificate_details.public_key_compressed )))); } } else { if (p_certificate_details.public_key_compressed_mode == 0) { v_publicVerificationKey := valueof( m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaBrainpoolP384r1( m_eccP384CurvePoint_compressed_y_0( p_certificate_details.public_key_compressed )))); } else { v_publicVerificationKey := valueof( m_verificationKeyIndicator_verificationKey( m_publicVerificationKey_ecdsaBrainpoolP384r1( m_eccP384CurvePoint_compressed_y_1( p_certificate_details.public_key_compressed )))); } } p_certificate_details.certificate := valueof( m_etsiTs103097Certificate( m_issuerIdentifier_self(p_certificate_params.hash_algorithm), m_toBeSignedCertificate( { name := p_certificate_params.certificate_id }, v_publicVerificationKey, p_certificate_params.validity_period, p_certificate_params.region, p_certificate_params.app_permissions, p_certificate_params.issuing_permissions ) ) ); if (p_certificate_params.encryption_key == true) { if (p_certificate_params.encryption_curve == e_nist_p256) { p_certificate_details.certificate.toBeSigned.encryptionKey := valueof(m_encryptionKey( aes128Ccm, m_publicEncryptionKey_ecdsaNistP256( m_eccP256CurvePoint_uncompressed( p_certificate_details.public_enc_key_x, p_certificate_details.public_enc_key_y ))) ); } else if (p_certificate_params.encryption_curve == e_brainpool_p256) { p_certificate_details.certificate.toBeSigned.encryptionKey := valueof(m_encryptionKey( aes128Ccm, m_publicEncryptionKey_eciesBrainpoolP256r1( m_eccP256CurvePoint_uncompressed( p_certificate_details.public_enc_key_x, p_certificate_details.public_enc_key_y ))) ); } } return 0; } // End of function f_fill_certificate function f_generate_certificate( in certificate_params p_certificate_params, in certificate_details p_issuer_certificate_details, inout certificate_details p_certificate_details ) return integer { var bitstring v_enc_msg; var octetstring v_raw_to_be_signed; var octetstring v_signature; // Encode it ==> Get octetstring v_enc_msg := encvalue(p_certificate_details.certificate.toBeSigned); v_raw_to_be_signed := bit2oct(v_enc_msg); if (p_issuer_certificate_details.issuer != p_issuer_certificate_details.hashid8) { // This is not a CA certificate v_raw_to_be_signed := v_raw_to_be_signed & p_issuer_certificate_details.issuer; } // Sign the certificate using ECDSA/SHA-256 (NIST p-256) if (p_certificate_params.curve == e_nist_p256) { v_signature := f_signWithEcdsaNistp256WithSha256(v_raw_to_be_signed, p_issuer_certificate_details.private_key); if (lengthof(v_signature) != 64) { setverdict(fail, "Wrong signature size, shall be 64 instead of ", lengthof(v_signature)); stop; } p_certificate_details.certificate.signature_ := valueof( m_signature_ecdsaNistP256( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_signature, 0, 32) ), substr(v_signature, 32, 32) ) )); } else if (p_certificate_params.curve == e_brainpool_p256) { v_signature := f_signWithEcdsaBrainpoolp256WithSha256(v_raw_to_be_signed, p_issuer_certificate_details.private_key); if (lengthof(v_signature) != 64) { setverdict(fail, "Wrong signature size, shall be 64 instead of ", lengthof(v_signature)); stop; } p_certificate_details.certificate.signature_ := valueof( m_signature_ecdsaBrainpoolP256r1( m_ecdsaP256Signature( m_eccP256CurvePoint_x_only( substr(v_signature, 0, 32) ), substr(v_signature, 32, 32) ) )); } else if (p_certificate_params.curve == e_brainpool_p384) { v_signature := f_signWithEcdsaBrainpoolp384WithSha384(v_raw_to_be_signed, p_issuer_certificate_details.private_key); if (lengthof(v_signature) != 96) { setverdict(fail, "Wrong signature size, shall be 96 instead of ", lengthof(v_signature)); stop; } p_certificate_details.certificate.signature_ := valueof(m_signature_ecdsaBrainpoolP384r1( m_ecdsaP384Signature( m_eccP384CurvePoint_x_only( substr(v_signature, 0, 48) ), substr(v_signature, 48, 48) ) )); } else { log("f_generate_certificate: Unsupported curve"); return -1; } return 0; } // End of function f_generate_certificate function f_finalyse_certificate( in certificate_params p_certificate_params, in certificate_details_list p_certificate_details_list, inout certificate_details p_certificate_details ) return integer { // Set the issuer if (p_certificate_params.certificate_id != p_certificate_params.signed_by) { // Find the issuer in the list var boolean v_found := false; for (var integer v_counter := 0; v_counter < lengthof(p_certificate_details_list); v_counter := v_counter + 1) { log("f_finalyse_certificate: compare ", p_certificate_details_list[v_counter].certificate_id, " with ", p_certificate_params.signed_by); if (p_certificate_details_list[v_counter].certificate_id == p_certificate_params.signed_by) { log("f_finalyse_certificate: Got it"); v_found := true; p_certificate_details.issuer := p_certificate_details_list[v_counter].hashid8; if (p_certificate_params.hash_algorithm == sha256) { p_certificate_details.certificate.issuer.sha256AndDigest := p_certificate_details_list[v_counter].hashid8; } else if (p_certificate_params.hash_algorithm == sha384) { p_certificate_details.certificate.issuer.sha384AndDigest := p_certificate_details_list[v_counter].hashid8; } else { log("f_finalyse_certificate: Unsupported hash algorithm"); return -1; } break; } } // End of 'for' statement if (v_found == false) { log("f_finalyse_certificate: issuer not found"); return -1; } } // Encode the certificate p_certificate_details.enc_cert := bit2oct(encvalue(p_certificate_details.certificate)); // Calculate the HashedId8 if (p_certificate_params.hash_algorithm == sha256) { p_certificate_details.hashid8 := f_HashedId8FromSha256(f_hashWithSha256(p_certificate_details.enc_cert)); } else { p_certificate_details.hashid8 := f_HashedId8FromSha384(f_hashWithSha384(p_certificate_details.enc_cert)); } if (p_certificate_params.certificate_id == p_certificate_params.signed_by) { // Root certificate log("f_finalyse_certificate: Root certificate"); p_certificate_details.issuer := p_certificate_details.hashid8 } return 0; } // End of function f_finalyse_certificate function f_store_certificates( in certificate_details_list p_certificate_details_list ) return integer { fx_loadCertificates(PX_CERTIFICATE_POOL_PATH, PX_IUT_SEC_CONFIG_NAME); for (var integer v_counter := 0; v_counter < lengthof(p_certificate_details_list); v_counter := v_counter + 1) { log("f_store_certificates: ", p_certificate_details_list[v_counter]); if (ispresent(p_certificate_details_list[v_counter].private_enc_key)) { fx_store_certificate( p_certificate_details_list[v_counter].certificate_id, p_certificate_details_list[v_counter].enc_cert, p_certificate_details_list[v_counter].private_key, p_certificate_details_list[v_counter].public_key_x, p_certificate_details_list[v_counter].public_key_y, p_certificate_details_list[v_counter].public_key_compressed, p_certificate_details_list[v_counter].public_key_compressed_mode, p_certificate_details_list[v_counter].hashid8, p_certificate_details_list[v_counter].issuer, p_certificate_details_list[v_counter].private_enc_key, p_certificate_details_list[v_counter].public_enc_key_x, p_certificate_details_list[v_counter].public_enc_key_y); } else { fx_store_certificate( p_certificate_details_list[v_counter].certificate_id, p_certificate_details_list[v_counter].enc_cert, p_certificate_details_list[v_counter].private_key, p_certificate_details_list[v_counter].public_key_x, p_certificate_details_list[v_counter].public_key_y, p_certificate_details_list[v_counter].public_key_compressed, p_certificate_details_list[v_counter].public_key_compressed_mode, p_certificate_details_list[v_counter].hashid8, p_certificate_details_list[v_counter].issuer, ''O, ''O, ''O); } } // End of 'for' statement return 0; } // End of function f_store_certificates } // End of module ItsGenCert_Functions