Newer
Older
/**
* @author ETSI / STF481
* @version $URL$
* $Id$
* @desc Module containing functions for Security Protocol
*
*/
module LibItsSecurity_Functions {
garciay
committed
import from LibCommon_DataStrings all;
garciay
committed
// LibItsCommon
import from LibItsCommon_Functions all;
import from LibItsSecurity_TypesAndValues all;
garciay
committed
import from LibItsSecurity_Templates all;
import from LibItsSecurity_Pixits 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(in octetstring p_toBeHashedData) return Oct32 {
return fx_hashWithSha256(p_toBeHashedData);
} // End of function f_hashWithSha256
/**
* @desc Produces a Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
* @param p_toBeSignedData The data to be signed
* @return The signature value
function f_signWithEcdsaNistp256WithSha256(in Oct32 p_toBeSignedData) return octetstring {
return fx_signWithEcdsaNistp256WithSha256(
p_toBeSignedData,
PX_PRIVATE_SIGNING_KEYS[PX_CERTIFICATE_CONFIG_IDX]
);
} // End of function f_signWithEcdsaNistp256WithSha256
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_signature The signature
* @param p_ecdsaNistp256PublicKeyX The public key (x coordinate)
* @param p_ecdsaNistp256PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
garciay
committed
function f_verifyWithEcdsaNistp256WithSha256(
in octetstring p_toBeVerifiedData,
in octetstring p_signature,
in octetstring p_ecdsaNistp256PublicKeyX,
in octetstring p_ecdsaNistp256PublicKeyY
) return boolean {
return fx_verifyWithEcdsaNistp256WithSha256(
p_toBeVerifiedData,
p_signature,
p_ecdsaNistp256PublicKeyX,
p_ecdsaNistp256PublicKeyY);
} // End of function f_verifyWithEcdsaNistp256WithSha256
/**
* @desc Calculate digest over the certificate
* @param cert The certificate
* @return the digest
*/
function f_calculateDigest(in Certificate cert) return HashedId8 {
garciay
committed
/**
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_unsecuredPayload The unsigned payload (e.g. a beacon)
* @param p_threeDLocation The ThreeDLocation value
* @param p_securedMessage The signed SecureMessage part
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_buildGnSecuredCam(
in octetstring p_unsecuredPayload,
in ThreeDLocation p_threeDLocation,
out template (value) SecuredMessage p_securedMessage)
return boolean {
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Local variables
var octetstring v_secPayload, v_signature;
var Oct32 v_hash;
var template (value) ToBeSignedData v_toBeSignedData;
// Create SecuredMessage payload to be signed
v_toBeSignedData := m_toBeSignedData_profileOther(
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
PX_AT_CERTIFICATES[PX_CERTIFICATE_CONFIG_IDX]
) // End of template m_signerInfo_certificate
), // End of template m_header_field_signer_info
m_header_field_generation_time(f_getCurrentTime()),
m_header_field_generation_location(
p_threeDLocation
),
m_header_field_message_type(c_messageType_CAM)
}, // End of field HeaderFields
{
m_payload_unsecured(
p_unsecuredPayload
)
}, // End of field HeaderFields
e_signature
);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
// log("v_secPayload: ", v_secPayload);
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// log("v_hash: ", v_hash);
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
);
// log("v_signature: ", v_signature);
p_securedMessage := m_securedMessage_profileOther( // See Clause 7.3 Generic security profile for other signed messages
v_toBeSignedData.header_fields,
v_toBeSignedData.payload_fields,
{
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)
)
)
)
}
); // End of template m_securedMessageBeacon
return true;
garciay
committed
}
/**
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_unsecuredPayload The unsigned payload (e.g. a beacon)
* @param p_threeDLocation The ThreeDLocation value
* @param p_securedMessage The signed SecureMessage part
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_buildGnSecuredDenm(
in octetstring p_unsecuredPayload,
in ThreeDLocation p_threeDLocation,
out template (value) SecuredMessage p_securedMessage)
return boolean {
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
// Local variables
var octetstring v_secPayload, v_signature;
var Oct32 v_hash;
var template (value) ToBeSignedData v_toBeSignedData;
// Create SecuredMessage payload to be signed
v_toBeSignedData := m_toBeSignedData_profileOther(
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
PX_AT_CERTIFICATES[PX_CERTIFICATE_CONFIG_IDX]
) // End of template m_signerInfo_certificate
), // End of template m_header_field_signer_info
m_header_field_generation_time(f_getCurrentTime()),
m_header_field_generation_location(
p_threeDLocation
),
m_header_field_message_type(c_messageType_DENM)
}, // End of field HeaderFields
{
m_payload_unsecured(
p_unsecuredPayload
)
}, // End of field HeaderFields
e_signature
);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
// log("v_secPayload: ", v_secPayload);
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// log("v_hash: ", v_hash);
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
);
// log("v_signature: ", v_signature);
p_securedMessage := m_securedMessage_profileOther( // See Clause 7.3 Generic security profile for other signed messages
v_toBeSignedData.header_fields,
v_toBeSignedData.payload_fields,
{
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)
)
)
)
}
); // End of template m_securedMessageBeacon
return true;
} // End of function f_buildGnSecuredDenm
garciay
committed
/**
* @desc This function build and sign the SecureMessage part covered by the signature process
* @param p_unsecuredPayload The unsigned payload (e.g. a beacon)
* @param p_threeDLocation The ThreeDLocation value
* @param p_securedMessage The signed SecureMessage part
* @return true on success, false otherwise
* @verdict Unchanged
*/
function f_buildGnSecuredOtherMessage(
in octetstring p_unsecuredPayload,
in ThreeDLocation p_threeDLocation,
out template (value) SecuredMessage p_securedMessage)
garciay
committed
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
return boolean {
// Local variables
var octetstring v_secPayload, v_signature;
var Oct32 v_hash;
var template (value) ToBeSignedData v_toBeSignedData;
// Create SecuredMessage payload to be signed
v_toBeSignedData := m_toBeSignedData_profileOther(
{ // Field HeaderFields
m_header_field_signer_info(
m_signerInfo_certificate(
PX_AT_CERTIFICATES[PX_CERTIFICATE_CONFIG_IDX]
) // End of template m_signerInfo_certificate
), // End of template m_header_field_signer_info
m_header_field_generation_time(f_getCurrentTime()),
m_header_field_generation_location(
p_threeDLocation
)
}, // End of field HeaderFields
{
m_payload_unsecured(
p_unsecuredPayload
)
}, // End of field HeaderFields
e_signature
);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
// log("f_buildGnSecuredOtherMessage: v_secPayload: ", v_secPayload);
garciay
committed
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// log("f_buildGnSecuredOtherMessage: v_hash: ", v_hash);
garciay
committed
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
garciay
committed
);
// log("f_buildGnSecuredOtherMessage: v_signature: ", v_signature);
garciay
committed
p_securedMessage := m_securedMessage_profileOther( // See Clause 7.3 Generic security profile for other signed messages
v_toBeSignedData.header_fields,
v_toBeSignedData.payload_fields,
{
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)
)
)
)
}
); // End of template m_securedMessageBeacon
return true;
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
} // End of function f_buildGnSecuredOtherMessage
/**
*
* @desc Verify the signature of the prvided secured message
* @param p_securedMessage
* @return true on success, false otherwise
* @verdict
*/
function f_verifyGnSecuredOtherMessage(
in template (value) SecuredMessage p_securedMessage)
return boolean {
// Local variables
var octetstring v_secPayload;
var octetstring v_signedData;
var Oct32 v_hash;
var integer v_counter;
var boolean v_result := false;
var template (value) ToBeSignedData v_toBeSignedData;
// Create SecuredMessage payload to be signed
v_toBeSignedData := m_toBeSignedData_profileOther(
p_securedMessage.header_fields,
p_securedMessage.payload_fields,
e_signature
);
v_secPayload := bit2oct(encvalue(v_toBeSignedData));
// log("f_verifyGnSecuredOtherMessage: v_secPayload: ", v_secPayload);
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := fx_hashWithSha256(v_secPayload);
// log("f_verifyGnSecuredOtherMessage: v_hash: ", v_hash);
// Verify payload
for (v_counter := 0; v_counter < lengthof(p_securedMessage.trailer_fields); v_counter := v_counter + 1) {
if (
(p_securedMessage.trailer_fields[v_counter].type_ == e_signature) and
(p_securedMessage.trailer_fields[v_counter].trailerField.signature_.algorithm == e_ecdsa_nistp256_with_sha256)
) {
v_signedData :=
'0000'O &
p_securedMessage.trailer_fields[v_counter].trailerField.signature_.signature_.ecdsa_signature.r.x &
p_securedMessage.trailer_fields[v_counter].trailerField.signature_.signature_.ecdsa_signature.s;
// log("f_verifyGnSecuredOtherMessage: v_signedData: ", v_signedData);
v_result := f_verifyWithEcdsaNistp256WithSha256(
v_hash,
v_signedData,
PX_AT_CERTIFICATES[PX_CERTIFICATE_CONFIG_IDX].subject_attributes[0].attribute.key.public_key.eccPoint.x,
PX_AT_CERTIFICATES[PX_CERTIFICATE_CONFIG_IDX].subject_attributes[0].attribute.key.public_key.eccPoint.y.y
);
}
} // End of 'for' statement
return v_result;
} // End of function f_verifyGnSecuredOtherMessage
garciay
committed
* @desc return SecuredMessage header field of given type or null if none
* @param p_msg the SecuredMessage
* @param p_type header field type
* @return HeaderField of given type if any or null
*/
function f_getMsgHeaderField(in SecuredMessage p_msg, in HeaderFieldType p_type)
return HeaderField {
var HeaderField v_return := null;
var integer v_length := lengthof(p_msg.header_fields);
var integer v_i;
for(v_i := 0; v_i < v_length; v_i := v_i + 1){
if(p_msg.header_fields[v_i].type_ == p_type){
v_return := p_msg.header_fields[v_i];
break;
}
}
return v_return;
}
/**
* @desc return SignerInfo SecuredMessage field
*/
function f_getMsgSignerInfo(in SecuredMessage p_msg) return SignerInfo {
var HeaderField v_hf := f_getMsgHeaderField(p_msg, e_signer_info);
return v_hf.headerField.signer;
}
return null;
}
}// End of group messageGetters
group certificateGetters {
function f_getCertificateValidityRestriction(in Certificate p_cert, in ValidityRestrictionType p_type)
return ValidityRestriction {
var ValidityRestriction v_return := null;
var integer v_length := lengthof(p_cert.validity_restrictions);
var integer v_index;
for( v_index := 0; v_index < v_length; v_index := v_index + 1 ) {
if( p_cert.validity_restrictions[v_index].type_ == p_type ) {
v_return := p_cert.validity_restrictions[v_index];
break;
}
}
return v_return;
}
function f_getCertificateSignerInfo (in Certificate p_cert)
return SignerInfo {
var SignerInfo ret := null;
if( lengthof(p_cert.signer_infos) > 0 ) {
ret := p_cert.signer_infos[0];
}
return ret;
}
group CertRequests{
function f_askForCertificateChain (in HashedId3s p_digests) {
}
} // End of group CertRequests
} // End of group helpersFunctions
group externalFunctions {
/**
* @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 Elliptic Curve Digital Signature Algorithm (ECDSA) signaturee
* @param p_toBeSignedData The data to be signed
* @param p_privateKey The private key
* @return The signature value
*/
external function fx_signWithEcdsaNistp256WithSha256(in octetstring p_toBeSignedData, in octetstring/*UInt64*/ p_privateKey) return octetstring;
/**
* @desc Verify the signature of the specified data
* @param p_toBeVerifiedData The data to be verified
* @param p_signature The signature
* @param p_ecdsaNistp256PublicKeyX The public key (x coordinate)
* @param p_ecdsaNistp256PublicKeyY The public key (y coordinate)
* @return true on success, false otherwise
*/
external function fx_verifyWithEcdsaNistp256WithSha256(in octetstring p_toBeVerifiedData, in octetstring p_signature, in octetstring p_ecdsaNistp256PublicKeyX, in octetstring p_ecdsaNistp256PublicKeyY) 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)
* @return true on success, false otherwise
*/
external function fx_generateKeyPair(out octetstring/*UInt64*/ p_privateKey, out octetstring p_publicKeyX, out octetstring p_publicKeyY) return boolean;
} // End of group externalFunctions