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(
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 {
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
* @desc Build a template of a secured beacon to be used for the Test Adapter secured beaconing processing
*/
function f_buildSecuredMessagePayloadToBeSigned()
return ToBeSignedData {
// Local variables
var template (value) ToBeSignedData v_toBeSignedData;
// Build the beacon template
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(oct2int('BBBBBBBB'O)), // To be replaced by TA with current time
m_header_field_generation_location(
PX_THREED_LOCATIONS[PX_CERTIFICATE_CONFIG_IDX]
)
}, // End of field HeaderFields
{
m_payload_unsecured(
'AAAAAAAAAA'O // To be replaced by TA with real payload
)
}, // End of field HeaderFields
e_signature
);
return v_toBeSignedData;
}
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
* @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 {
// 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));
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
);
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;
}
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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/**
* @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 {
// 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));
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
);
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
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
/**
* @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
) 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));
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := f_hashWithSha256(v_secPayload);
// Signed payload
v_signature := f_signWithEcdsaNistp256WithSha256(
v_hash
);
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)
)
garciay
committed
)
)
}
); // End of template m_securedMessageBeacon
return true;
} // End of function f_buildGnSecuredOtherMessage
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
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
/**
*
* @desc Verify the signature of the provided 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));
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := fx_hashWithSha256(v_secPayload);
// 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;
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
} // End of group hostSignatureHelpers
group deviceSignatureHelpers {
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
/**
* @desc Verify the signature of the provided secured message
* @param p_securedMessage
* @return true on success, false otherwise
* @verdict
*/
function f_verifyGnSecuredOtherMessageWithDeviceCertificate(
in template (value) SecuredMessage p_securedMessage,
in template (value) Certificate p_certificate
) 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));
// Calculate the hash of the SecuredMessage payload to be signed
v_hash := fx_hashWithSha256(v_secPayload);
// 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;
v_result := f_verifyWithEcdsaNistp256WithSha256(
v_hash,
v_signedData,
p_certificate.subject_attributes[0].attribute.key.public_key.eccPoint.x,
p_certificate.subject_attributes[0].attribute.key.public_key.eccPoint.y.y
);
}
} // End of 'for' statement
return v_result;
} // End of function f_verifyGnSecuredOtherMessageWithDeviceCertificate
} // End of group deviceSignatureHelpers
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_securedMessage,
in HeaderFieldType p_headerFieldType
) return HeaderField {
var HeaderField v_return;
var integer v_length := lengthof(p_securedMessage.header_fields);
var integer v_index;
for (v_index := 0; v_index < v_length; v_index := v_index + 1) {
if (p_securedMessage.header_fields[v_index].type_ == p_headerFieldType) {
v_return := p_securedMessage.header_fields[v_index];
break;
}
}
return v_return;
}
/**
* @desc return SignerInfo SecuredMessage field
*/
function f_getMsgSignerInfo(
in SecuredMessage p_securedMessage
) return SignerInfo {
var HeaderField v_hf := f_getMsgHeaderField(p_securedMessage, 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;
var integer v_length := lengthof(p_cert.validity_restrictions);
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;
if (lengthof(p_cert.signer_infos) > 0) {
ret := p_cert.signer_infos[0];
}
return ret;
}
function f_askForCertificateChain (in HashedId3s p_digests) {
} // 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