Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ITS - Intelligent Transport Systems
ITS
Commits
2c994fad
Commit
2c994fad
authored
Mar 24, 2020
by
Yann Garcia
Browse files
Bug fixed in Native API
parent
cb8cf8a4
Changes
6
Hide whitespace changes
Inline
Side-by-side
tools/itssecurity/.vs/itssecurity/v16/.suo
View file @
2c994fad
No preview for this file type
tools/itssecurity/.vs/itssecurity/v16/Browse.VC.db
View file @
2c994fad
No preview for this file type
tools/itssecurity/.vs/itssecurity/v16/Solution.VC.db
View file @
2c994fad
No preview for this file type
tools/itssecurity/lib_its_security/lib_its_security.c
View file @
2c994fad
...
...
@@ -28,484 +28,487 @@
*/
void
show_ec_key
(
const
int8_t
*
p_prefix
,
lib_its_security_context_t
*
p_lib_its_security_context
)
{
fprintf
(
stderr
,
"%s: "
,
p_prefix
);
BIGNUM
*
x
=
BN_new
();
BIGNUM
*
y
=
BN_new
();
const
EC_POINT
*
keys
=
EC_KEY_get0_public_key
(
p_lib_its_security_context
->
ec_key
);
if
(
EC_POINT_get_affine_coordinates_GFp
(
p_lib_its_security_context
->
ec_group
,
keys
,
x
,
y
,
NULL
))
{
BN_print_fp
(
stderr
,
x
);
fprintf
(
stderr
,
"
\n
"
);
BN_print_fp
(
stderr
,
y
);
fprintf
(
stderr
,
"
\n
"
);
}
BN_free
(
x
);
BN_free
(
y
);
fprintf
(
stderr
,
"%s: "
,
p_prefix
);
BIGNUM
*
x
=
BN_new
();
BIGNUM
*
y
=
BN_new
();
const
EC_POINT
*
keys
=
EC_KEY_get0_public_key
(
p_lib_its_security_context
->
ec_key
);
if
(
EC_POINT_get_affine_coordinates_GFp
(
p_lib_its_security_context
->
ec_group
,
keys
,
x
,
y
,
NULL
))
{
BN_print_fp
(
stderr
,
x
);
fprintf
(
stderr
,
"
\n
"
);
BN_print_fp
(
stderr
,
y
);
fprintf
(
stderr
,
"
\n
"
);
}
BN_free
(
x
);
BN_free
(
y
);
}
void
show_ec_point
(
const
int8_t
*
p_prefix
,
lib_its_security_context_t
*
p_lib_its_security_context
,
EC_POINT
*
p_ec_point
)
{
fprintf
(
stderr
,
"%s: "
,
p_prefix
);
char
*
result
=
EC_POINT_point2hex
(
p_lib_its_security_context
->
ec_group
,
p_ec_point
,
POINT_CONVERSION_UNCOMPRESSED
,
p_lib_its_security_context
->
bn_ctx
);
if
(
result
!=
NULL
)
{
fprintf
(
stderr
,
"%s
\n
"
,
result
);
fprintf
(
stderr
,
"%s: "
,
p_prefix
);
char
*
result
=
EC_POINT_point2hex
(
p_lib_its_security_context
->
ec_group
,
p_ec_point
,
POINT_CONVERSION_UNCOMPRESSED
,
p_lib_its_security_context
->
bn_ctx
);
if
(
result
!=
NULL
)
{
fprintf
(
stderr
,
"%s
\n
"
,
result
);
#ifdef _Win64
free
(
result
);
free
(
result
);
#endif
}
else
{
fprintf
(
stderr
,
"(null)
\n
"
);
}
}
else
{
fprintf
(
stderr
,
"(null)
\n
"
);
}
}
void
show_hex
(
const
int8_t
*
p_prefix
,
const
void
*
p_buffer
,
size_t
p_buffer_length
)
{
fprintf
(
stderr
,
"%s: "
,
p_prefix
);
for
(
uint8_t
*
p
=
(
unsigned
char
*
)
p_buffer
;
p_buffer_length
;
p_buffer_length
--
,
p
++
)
{
fprintf
(
stderr
,
"%02x"
,
*
p
);
}
putc
(
'\n'
,
stderr
);
fprintf
(
stderr
,
"%s: "
,
p_prefix
);
for
(
uint8_t
*
p
=
(
unsigned
char
*
)
p_buffer
;
p_buffer_length
;
p_buffer_length
--
,
p
++
)
{
fprintf
(
stderr
,
"%02x"
,
*
p
);
}
putc
(
'\n'
,
stderr
);
}
int8_t
*
bin_to_hex
(
const
uint8_t
*
p_buffer
,
const
size_t
p_buffer_length
)
{
int8_t
*
buf
=
NULL
;
size_t
i
=
0
,
j
=
0
;
// Sanity check
if
(
p_buffer_length
==
0
)
{
return
NULL
;
}
buf
=
(
int8_t
*
)
malloc
(
p_buffer_length
<<
1
);
do
{
*
(
buf
+
j
)
=
"0123456789ABCDEF"
[(
*
(
p_buffer
+
i
)
>>
4
)
&
0x0F
];
*
(
buf
+
j
+
1
)
=
"0123456789ABCDEF"
[
*
(
p_buffer
+
i
)
&
0x0F
];
i
+=
1
;
j
+=
2
;
}
while
(
i
<
p_buffer_length
);
return
buf
;
int8_t
*
buf
=
NULL
;
size_t
i
=
0
,
j
=
0
;
// Sanity check
if
(
p_buffer_length
==
0
)
{
return
NULL
;
}
buf
=
(
int8_t
*
)
malloc
(
p_buffer_length
<<
1
);
do
{
*
(
buf
+
j
)
=
"0123456789ABCDEF"
[(
*
(
p_buffer
+
i
)
>>
4
)
&
0x0F
];
*
(
buf
+
j
+
1
)
=
"0123456789ABCDEF"
[
*
(
p_buffer
+
i
)
&
0x0F
];
i
+=
1
;
j
+=
2
;
}
while
(
i
<
p_buffer_length
);
return
buf
;
}
uint8_t
*
hex_to_bin
(
const
int8_t
*
p_buffer
,
size_t
*
p_buffer_length
)
{
int8_t
a
;
size_t
i
,
len
;
uint8_t
*
retval
=
NULL
;
// Sanity check
if
(
p_buffer
==
NULL
)
{
return
NULL
;
}
if
((
len
=
strlen
((
const
char
*
)
p_buffer
))
&
1
)
{
return
NULL
;
}
retval
=
(
uint8_t
*
)
malloc
(
len
>>
1
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
a
=
toupper
(
*
(
p_buffer
+
i
));
if
(
!
isxdigit
(
a
))
{
break
;
}
if
(
isdigit
(
a
))
{
a
-=
'0'
;
}
else
{
a
=
a
-
'A'
+
0x0A
;
}
if
(
i
&
1
)
{
retval
[
i
>>
1
]
|=
a
;
}
else
{
retval
[
i
>>
1
]
=
a
<<
4
;
}
}
// End of 'for' statement
if
(
i
<
len
)
{
free
(
retval
);
retval
=
NULL
;
}
*
p_buffer_length
=
len
>>
1
;
return
retval
;
int8_t
a
;
size_t
i
,
len
;
uint8_t
*
retval
=
NULL
;
// Sanity check
if
(
p_buffer
==
NULL
)
{
return
NULL
;
}
if
((
len
=
strlen
((
const
char
*
)
p_buffer
))
&
1
)
{
return
NULL
;
}
retval
=
(
uint8_t
*
)
malloc
(
len
>>
1
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
a
=
toupper
(
*
(
p_buffer
+
i
));
if
(
!
isxdigit
(
a
))
{
break
;
}
if
(
isdigit
(
a
))
{
a
-=
'0'
;
}
else
{
a
=
a
-
'A'
+
0x0A
;
}
if
(
i
&
1
)
{
retval
[
i
>>
1
]
|=
a
;
}
else
{
retval
[
i
>>
1
]
=
a
<<
4
;
}
}
// End of 'for' statement
if
(
i
<
len
)
{
free
(
retval
);
retval
=
NULL
;
}
*
p_buffer_length
=
len
>>
1
;
return
retval
;
}
int32_t
sign
(
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_data
,
const
size_t
p_data_length
,
uint8_t
**
p_sig_r
,
uint8_t
**
p_sig_s
,
size_t
*
p_sig_length
)
{
// Sanity checks
if
((
p_lib_its_security_context
==
NULL
)
||
(
p_data
==
NULL
))
{
return
-
1
;
}
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_data
,
const
size_t
p_data_length
,
uint8_t
**
p_sig_r
,
uint8_t
**
p_sig_s
,
size_t
*
p_sig_length
)
{
// Sanity checks
if
((
p_lib_its_security_context
==
NULL
)
||
(
p_data
==
NULL
))
{
return
-
1
;
}
ECDSA_SIG
*
signature
=
ECDSA_do_sign
(
p_data
,
p_data_length
,
p_lib_its_security_context
->
ec_key
);
if
(
signature
==
NULL
)
{
return
-
1
;
}
ECDSA_SIG
*
signature
=
ECDSA_do_sign
(
p_data
,
p_data_length
,
p_lib_its_security_context
->
ec_key
);
if
(
signature
==
NULL
)
{
return
-
1
;
}
if
(
ECDSA_do_verify
(
p_data
,
p_data_length
,
signature
,
p_lib_its_security_context
->
ec_key
)
!=
1
)
{
return
-
1
;
}
if
(
ECDSA_do_verify
(
p_data
,
p_data_length
,
signature
,
p_lib_its_security_context
->
ec_key
)
!=
1
)
{
return
-
1
;
}
const
BIGNUM
*
r
;
const
BIGNUM
*
s
;
ECDSA_SIG_get0
(
signature
,
&
r
,
&
s
);
*
p_sig_length
=
BN_num_bytes
(
s
);
*
p_sig_r
=
(
uint8_t
*
)
malloc
(
*
p_sig_length
);
BN_bn2bin
(
r
,
(
uint8_t
*
)(
*
p_sig_r
));
*
p_sig_s
=
(
uint8_t
*
)
malloc
(
*
p_sig_length
);
BN_bn2bin
(
s
,
(
uint8_t
*
)(
*
p_sig_s
));
const
BIGNUM
*
r
;
const
BIGNUM
*
s
;
ECDSA_SIG_get0
(
signature
,
&
r
,
&
s
);
*
p_sig_length
=
BN_num_bytes
(
s
);
*
p_sig_r
=
(
uint8_t
*
)
malloc
(
*
p_sig_length
);
BN_bn2bin
(
r
,
(
uint8_t
*
)(
*
p_sig_r
));
*
p_sig_s
=
(
uint8_t
*
)
malloc
(
*
p_sig_length
);
BN_bn2bin
(
s
,
(
uint8_t
*
)(
*
p_sig_s
));
ECDSA_SIG_free
(
signature
);
ECDSA_SIG_free
(
signature
);
return
0
;
return
0
;
}
int32_t
sign_verify
(
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_data
,
const
size_t
p_data_length
,
const
uint8_t
*
p_sig_r
,
const
uint8_t
*
p_sig_s
,
const
size_t
p_sig_length
)
{
show_hex
((
const
int8_t
*
)
">>> sign_verify: p_data"
,
p_data
,
p_data_length
);
show_hex
((
const
int8_t
*
)
">>> sign_verify: p_sig_r"
,
p_sig_r
,
p_sig_length
);
show_hex
((
const
int8_t
*
)
">>> sign_verify: p_sig_s"
,
p_sig_s
,
p_sig_length
);
// Sanity checks
if
((
p_lib_its_security_context
==
NULL
)
||
(
p_data
==
NULL
)
||
(
p_sig_r
==
NULL
)
||
(
p_sig_s
==
NULL
))
{
return
-
1
;
}
// Build the signature
BIGNUM
*
r
=
BN_bin2bn
(
p_sig_r
,
p_sig_length
,
NULL
);
BIGNUM
*
s
=
BN_bin2bn
(
p_sig_s
,
p_sig_length
,
NULL
);
ECDSA_SIG
*
signature
=
ECDSA_SIG_new
();
ECDSA_SIG_set0
(
signature
,
r
,
s
);
// Check the signature
int32_t
result
=
ECDSA_do_verify
(
p_data
,
p_data_length
,
signature
,
p_lib_its_security_context
->
ec_key
);
fprintf
(
stderr
,
"sign_verify: result=%d
\n
"
,
result
);
ECDSA_SIG_free
(
signature
);
return
(
result
==
1
)
?
0
:
-
1
;
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_data
,
const
size_t
p_data_length
,
const
uint8_t
*
p_sig_r
,
const
uint8_t
*
p_sig_s
,
const
size_t
p_sig_length
)
{
show_hex
((
const
int8_t
*
)
">>> sign_verify: p_data"
,
p_data
,
p_data_length
);
show_hex
((
const
int8_t
*
)
">>> sign_verify: p_sig_r"
,
p_sig_r
,
p_sig_length
);
show_hex
((
const
int8_t
*
)
">>> sign_verify: p_sig_s"
,
p_sig_s
,
p_sig_length
);
// Sanity checks
if
((
p_lib_its_security_context
==
NULL
)
||
(
p_data
==
NULL
)
||
(
p_sig_r
==
NULL
)
||
(
p_sig_s
==
NULL
))
{
return
-
1
;
}
// Build the signature
BIGNUM
*
r
=
BN_bin2bn
(
p_sig_r
,
p_sig_length
,
NULL
);
BIGNUM
*
s
=
BN_bin2bn
(
p_sig_s
,
p_sig_length
,
NULL
);
ECDSA_SIG
*
signature
=
ECDSA_SIG_new
();
ECDSA_SIG_set0
(
signature
,
r
,
s
);
// Check the signature
int32_t
result
=
ECDSA_do_verify
(
p_data
,
p_data_length
,
signature
,
p_lib_its_security_context
->
ec_key
);
fprintf
(
stderr
,
"sign_verify: result=%d
\n
"
,
result
);
ECDSA_SIG_free
(
signature
);
return
(
result
==
1
)
?
0
:
-
1
;
}
int
bin_to_ec_point
(
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_public_key_x
,
const
uint8_t
*
p_public_key_y
,
EC_POINT
**
p_ec_point
)
{
BIGNUM
*
pubk_bn
=
NULL
;
size_t
l
=
2
*
p_lib_its_security_context
->
key_length
+
1
;
uint8_t
*
v
=
(
uint8_t
*
)
malloc
(
l
);
*
v
=
0x04
;
memcpy
((
void
*
)(
v
+
1
),
(
const
void
*
)
p_public_key_x
,
p_lib_its_security_context
->
key_length
);
memcpy
((
void
*
)(
v
+
1
+
p_lib_its_security_context
->
key_length
),
(
const
void
*
)
p_public_key_y
,
p_lib_its_security_context
->
key_length
);
pubk_bn
=
BN_bin2bn
(
v
,
l
,
NULL
);
*
p_ec_point
=
EC_POINT_new
(
p_lib_its_security_context
->
ec_group
);
EC_POINT_bn2point
(
p_lib_its_security_context
->
ec_group
,
pubk_bn
,
*
p_ec_point
,
p_lib_its_security_context
->
bn_ctx
);
BN_clear_free
(
pubk_bn
);
free
(
v
);
return
0
;
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_public_key_x
,
const
uint8_t
*
p_public_key_y
,
EC_POINT
**
p_ec_point
)
{
BIGNUM
*
pubk_bn
=
NULL
;
size_t
l
=
2
*
p_lib_its_security_context
->
key_length
+
1
;
uint8_t
*
v
=
(
uint8_t
*
)
malloc
(
l
);
*
v
=
0x04
;
memcpy
((
void
*
)(
v
+
1
),
(
const
void
*
)
p_public_key_x
,
p_lib_its_security_context
->
key_length
);
memcpy
((
void
*
)(
v
+
1
+
p_lib_its_security_context
->
key_length
),
(
const
void
*
)
p_public_key_y
,
p_lib_its_security_context
->
key_length
);
pubk_bn
=
BN_bin2bn
(
v
,
l
,
NULL
);
*
p_ec_point
=
EC_POINT_new
(
p_lib_its_security_context
->
ec_group
);
EC_POINT_bn2point
(
p_lib_its_security_context
->
ec_group
,
pubk_bn
,
*
p_ec_point
,
p_lib_its_security_context
->
bn_ctx
);
BN_clear_free
(
pubk_bn
);
free
(
v
);
return
0
;
}
int
public_key_to_bin
(
lib_its_security_context_t
*
p_lib_its_security_context
,
uint8_t
**
p_bin_key
)
{
const
EC_GROUP
*
ec_group
=
EC_KEY_get0_group
(
p_lib_its_security_context
->
ec_key
);
const
EC_POINT
*
pub
=
EC_KEY_get0_public_key
(
p_lib_its_security_context
->
ec_key
);
BIGNUM
*
pub_bn
=
BN_new
();
lib_its_security_context_t
*
p_lib_its_security_context
,
uint8_t
**
p_bin_key
)
{
const
EC_GROUP
*
ec_group
=
EC_KEY_get0_group
(
p_lib_its_security_context
->
ec_key
);
const
EC_POINT
*
pub
=
EC_KEY_get0_public_key
(
p_lib_its_security_context
->
ec_key
);
BIGNUM
*
pub_bn
=
BN_new
();
EC_POINT_point2bn
(
ec_group
,
pub
,
POINT_CONVERSION_UNCOMPRESSED
,
pub_bn
,
p_lib_its_security_context
->
bn_ctx
);
*
p_bin_key
=
(
uint8_t
*
)
malloc
(
BN_num_bytes
(
pub_bn
));
BN_bn2bin
(
pub_bn
,
*
p_bin_key
);
EC_POINT_point2bn
(
ec_group
,
pub
,
POINT_CONVERSION_UNCOMPRESSED
,
pub_bn
,
p_lib_its_security_context
->
bn_ctx
);
*
p_bin_key
=
(
uint8_t
*
)
malloc
(
BN_num_bytes
(
pub_bn
));
BN_bn2bin
(
pub_bn
,
*
p_bin_key
);
BN_clear_free
(
pub_bn
);
BN_clear_free
(
pub_bn
);
return
0
;
return
0
;
}
int
kdf2_sha256
(
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_salt
,
const
int32_t
p_salt_length
,
const
int32_t
p_key_length
,
uint8_t
**
p_digest
,
size_t
*
p_digest_length
)
{
// Sanity checks
int
sha256_blk_len
=
32
;
int
num_blk_out
=
(
int
)
ceil
(
p_key_length
/
(
float
)
sha256_blk_len
);
uint8_t
*
digest
=
(
uint8_t
*
)
malloc
((
num_blk_out
+
1
)
*
sha256_blk_len
);
int32_t
digest_idx
=
0
;
const
size_t
hash_input_length
=
p_lib_its_security_context
->
secret_key_length
+
sizeof
(
int32_t
)
+
p_salt_length
;
uint8_t
*
hash_input
=
(
uint8_t
*
)
malloc
(
hash_input_length
);
int
i_ntonl
;
for
(
int32_t
i
=
1
;
i
<
num_blk_out
+
1
;
i
++
)
{
uint8_t
*
p
=
hash_input
;
memcpy
((
void
*
)
p
,
(
const
void
*
)
p_lib_its_security_context
->
secret_key
,
p_lib_its_security_context
->
secret_key_length
);
p
+=
p_lib_its_security_context
->
secret_key_length
;
i_ntonl
=
htonl
(
i
);
memcpy
((
void
*
)
p
,
(
const
void
*
)
&
i_ntonl
,
sizeof
(
int32_t
));
p
+=
sizeof
(
int32_t
);
memcpy
((
void
*
)
p
,
(
const
void
*
)
p_salt
,
p_salt_length
);
//show_hex((const int8_t*)"hash_input", (const void*)hash_input, hash_input_length);
uint8_t
*
h
;
hash_with_sha256
(
hash_input
,
hash_input_length
,
&
h
);
//show_hex((const int8_t*)"h", (const void*)h, 32);
memcpy
((
void
*
)(
digest
+
digest_idx
),
(
const
void
*
)
h
,
sha256_blk_len
);
//show_hex((const int8_t*)"digest", (const void*)digest, digest_idx + sha256_blk_len);
digest_idx
+=
sha256_blk_len
;
free
(
h
);
}
// End of 'for' statement
free
(
hash_input
);
if
(
digest_idx
>
p_key_length
*
2
)
{
digest_idx
=
p_key_length
*
2
;
}
*
p_digest
=
(
uint8_t
*
)
malloc
(
digest_idx
);
memcpy
((
void
*
)(
*
p_digest
),
(
const
void
*
)
digest
,
digest_idx
);
*
p_digest_length
=
digest_idx
;
free
(
digest
);
return
0
;
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_salt
,
const
int32_t
p_salt_length
,
const
int32_t
p_key_length
,
uint8_t
**
p_digest
,
size_t
*
p_digest_length
)
{
// Sanity checks
int
sha256_blk_len
=
32
;
int
num_blk_out
=
(
int
)
ceil
(
p_key_length
/
(
float
)
sha256_blk_len
);
uint8_t
*
digest
=
(
uint8_t
*
)
malloc
((
num_blk_out
+
1
)
*
sha256_blk_len
);
int32_t
digest_idx
=
0
;
const
size_t
hash_input_length
=
p_lib_its_security_context
->
secret_key_length
+
sizeof
(
int32_t
)
+
p_salt_length
;
uint8_t
*
hash_input
=
(
uint8_t
*
)
malloc
(
hash_input_length
);
int
i_ntonl
;
for
(
int32_t
i
=
1
;
i
<
num_blk_out
+
1
;
i
++
)
{
uint8_t
*
p
=
hash_input
;
memcpy
((
void
*
)
p
,
(
const
void
*
)
p_lib_its_security_context
->
secret_key
,
p_lib_its_security_context
->
secret_key_length
);
p
+=
p_lib_its_security_context
->
secret_key_length
;
i_ntonl
=
htonl
(
i
);
memcpy
((
void
*
)
p
,
(
const
void
*
)
&
i_ntonl
,
sizeof
(
int32_t
));
p
+=
sizeof
(
int32_t
);
memcpy
((
void
*
)
p
,
(
const
void
*
)
p_salt
,
p_salt_length
);
//show_hex((const int8_t*)"hash_input", (const void*)hash_input, hash_input_length);
uint8_t
*
h
;
hash_with_sha256
(
hash_input
,
hash_input_length
,
&
h
);
//show_hex((const int8_t*)"h", (const void*)h, 32);
memcpy
((
void
*
)(
digest
+
digest_idx
),
(
const
void
*
)
h
,
sha256_blk_len
);
//show_hex((const int8_t*)"digest", (const void*)digest, digest_idx + sha256_blk_len);
digest_idx
+=
sha256_blk_len
;
free
(
h
);
}
// End of 'for' statement
free
(
hash_input
);
if
(
digest_idx
>
p_key_length
*
2
)
{
digest_idx
=
p_key_length
*
2
;
}
*
p_digest
=
(
uint8_t
*
)
malloc
(
digest_idx
);
memcpy
((
void
*
)(
*
p_digest
),
(
const
void
*
)
digest
,
digest_idx
);
*
p_digest_length
=
digest_idx
;
free
(
digest
);
return
0
;
}
int32_t
kdf2
(
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_salt
,
const
int32_t
p_salt_length
,
const
int32_t
p_key_length
,
const
unsigned
char
p_hash_algorithm
,
uint8_t
**
p_digest
,
size_t
*
p_digest_length
)
{
// Sanity checks
int
result
=
-
1
;
switch
(
p_hash_algorithm
)
{
case
0x00
:
// SHA 256
result
=
kdf2_sha256
(
p_lib_its_security_context
,
p_salt
,
p_salt_length
,
p_key_length
,
p_digest
,
p_digest_length
);
break
;
}
// End of 'switch' statement
return
result
;
lib_its_security_context_t
*
p_lib_its_security_context
,
const
uint8_t
*
p_salt
,
const
int32_t
p_salt_length
,
const
int32_t
p_key_length
,
const
unsigned
char
p_hash_algorithm
,
uint8_t
**
p_digest
,
size_t
*
p_digest_length
)
{
// Sanity checks
int
result
=
-
1
;
switch
(
p_hash_algorithm
)
{
case
0x00
:
// SHA 256
result
=
kdf2_sha256
(
p_lib_its_security_context
,
p_salt
,
p_salt_length
,
p_key_length
,
p_digest
,
p_digest_length
);
break
;
}
// End of 'switch' statement
return
result
;
}
int32_t
generate_and_derive_ephemeral_key_for_encryption
(
lib_its_security_context_t
*
p_ecdh_private_key
,
const
encryption_algorithm_t
p_enc_algorithm
,
lib_its_security_context_t
*
p_public_keys
,
const
uint8_t
*
p_salt
,
const
size_t
p_salt_length
)
{
// Sanity checks
if
(
p_public_keys
->
private_key
!=
NULL
)
{
return
-
1
;
}
if
((
p_public_keys
->
public_key_x
==
NULL
)
||
(
p_public_keys
->
public_key_y
==
NULL
))
{
return
-
1
;
}
// Set buffers size
p_ecdh_private_key
->
encryption_algorithm
=
p_enc_algorithm
;
switch
(
p_ecdh_private_key
->
encryption_algorithm
)
{
case
aes_128_ccm
:
// No break;
case
aes_128_gcm
:
p_ecdh_private_key
->
nonce_length
=
12
;
p_ecdh_private_key
->
sym_key_length
=
16
;
p_ecdh_private_key
->
tag_length
=
16
;
break
;
default:
return
-
1
;
}
// End of 'switch' statement
uint8_t
k_enc
;
uint8_t
k_mac
;
switch
(
p_ecdh_private_key
->
elliptic_curve
)
{
case
nist_p_256
:
// Use the ANSI X9.62 Prime 256v1 curve
// No break;
case
brainpool_p_256_r1
:
k_enc
=
16
;
k_mac
=
32
;
break
;
case
brainpool_p_384_r1
:
k_enc
=
24
;
// TODO To be checked
k_mac
=
48
;
break
;
default:
return
-
1
;
}
// End of 'switch' statement
/* Convert the ephemeral public encryption keys to an EC point */
EC_POINT
*
ec_point
=
NULL
;
bin_to_ec_point
(
p_public_keys
,
p_public_keys
->
public_key_x
,
p_public_keys
->
public_key_y
,
&
ec_point
);
show_ec_point
((
const
int8_t
*
)
"ec_point"
,
p_public_keys
,
ec_point
);
/* Generate the shared secret key (Key Agreement) */
p_ecdh_private_key
->
secret_key_length
=
(
EC_GROUP_get_degree
(
p_ecdh_private_key
->
ec_group
)
+
7
)
/
8
;
p_ecdh_private_key
->
secret_key
=
(
uint8_t
*
)
malloc
(
p_ecdh_private_key
->
secret_key_length
);
int32_t
result
=
ECDH_compute_key
(
p_ecdh_private_key
->
secret_key
,
p_ecdh_private_key
->
secret_key_length
,
ec_point
,
// From recipient's public keys
p_ecdh_private_key
->
ec_key
,
// From ephemeral's private key
NULL
);
if
(
result
!=
p_ecdh_private_key
->
secret_key_length
)
{
free
(
p_ecdh_private_key
->
secret_key
);
p_ecdh_private_key
->
secret_key
=
NULL
;
lib_its_security_context_t
*
p_ecdh_private_key
,
const
encryption_algorithm_t
p_enc_algorithm
,
lib_its_security_context_t
*
p_public_keys
,
const
uint8_t
*
p_salt
,
const
size_t
p_salt_length
)
{
// Sanity checks
if
(
p_public_keys
->
private_key
!=
NULL
)
{
return
-
1
;
}
if
((
p_public_keys
->
public_key_x
==
NULL
)
||
(
p_public_keys
->
public_key_y
==
NULL
))
{
return
-
1
;
}
// Set buffers size
p_ecdh_private_key
->
encryption_algorithm
=
p_enc_algorithm
;
switch
(
p_ecdh_private_key
->
encryption_algorithm
)
{
case
aes_128_ccm
:
// No break;