Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-RAN
Commits
252a7caf
Commit
252a7caf
authored
Apr 30, 2024
by
Jaroslava Fiedlerova
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/bugfix-speedup-integrity' into integration_2024_w17
parents
434b2b22
39a5e728
Changes
27
Hide whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
333 additions
and
280 deletions
+333
-280
openair2/LAYER2/PDCP_v10.1.0/pdcp.c
openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+8
-3
openair2/LAYER2/PDCP_v10.1.0/pdcp.h
openair2/LAYER2/PDCP_v10.1.0/pdcp.h
+6
-3
openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
+16
-13
openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
+8
-6
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c
+9
-10
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h
+5
-3
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
+8
-17
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h
+5
-3
openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
+4
-4
openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h
openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h
+5
-3
openair3/NAS/COMMON/API/NETWORK/nas_message.c
openair3/NAS/COMMON/API/NETWORK/nas_message.c
+7
-13
openair3/NAS/NR_UE/nr_nas_msg_sim.c
openair3/NAS/NR_UE/nr_nas_msg_sim.c
+8
-8
openair3/NAS/NR_UE/nr_nas_msg_sim.h
openair3/NAS/NR_UE/nr_nas_msg_sim.h
+2
-0
openair3/NAS/UE/EMM/SecurityModeControl.c
openair3/NAS/UE/EMM/SecurityModeControl.c
+7
-0
openair3/NAS/UE/EMM/emmData.h
openair3/NAS/UE/EMM/emmData.h
+2
-0
openair3/SECU/aes_128_cbc_cmac.c
openair3/SECU/aes_128_cbc_cmac.c
+48
-127
openair3/SECU/aes_128_cbc_cmac.h
openair3/SECU/aes_128_cbc_cmac.h
+3
-7
openair3/SECU/nas_stream_eea1.c
openair3/SECU/nas_stream_eea1.c
+22
-12
openair3/SECU/nas_stream_eea1.h
openair3/SECU/nas_stream_eea1.h
+3
-0
openair3/SECU/nas_stream_eea2.c
openair3/SECU/nas_stream_eea2.c
+14
-3
openair3/SECU/nas_stream_eea2.h
openair3/SECU/nas_stream_eea2.h
+3
-34
openair3/SECU/nas_stream_eia1.c
openair3/SECU/nas_stream_eia1.c
+19
-5
openair3/SECU/nas_stream_eia1.h
openair3/SECU/nas_stream_eia1.h
+3
-0
openair3/SECU/nas_stream_eia2.c
openair3/SECU/nas_stream_eia2.c
+16
-3
openair3/SECU/nas_stream_eia2.h
openair3/SECU/nas_stream_eia2.h
+3
-0
openair3/SECU/secu_defs.c
openair3/SECU/secu_defs.c
+67
-0
openair3/SECU/secu_defs.h
openair3/SECU/secu_defs.h
+32
-3
No files found.
openair2/LAYER2/PDCP_v10.1.0/pdcp.c
View file @
252a7caf
...
...
@@ -2124,9 +2124,12 @@ pdcp_config_set_security(
pdcp_pP
->
cipheringAlgorithm
,
pdcp_pP
->
integrityProtAlgorithm
);
kRRCenc
!=
NULL
?
memcpy
(
pdcp_pP
->
kRRCenc
,
kRRCenc
,
32
)
:
memset
(
pdcp_pP
->
kRRCenc
,
0
,
32
);
kRRCint
!=
NULL
?
memcpy
(
pdcp_pP
->
kRRCint
,
kRRCint
,
32
)
:
memset
(
pdcp_pP
->
kRRCint
,
0
,
32
);
kUPenc
!=
NULL
?
memcpy
(
pdcp_pP
->
kUPenc
,
kUPenc
,
32
)
:
memset
(
pdcp_pP
->
kUPenc
,
0
,
32
);
kRRCenc
!=
NULL
?
memcpy
(
pdcp_pP
->
kRRCenc
,
kRRCenc
+
16
,
16
)
:
memset
(
pdcp_pP
->
kRRCenc
,
0
,
16
);
kRRCint
!=
NULL
?
memcpy
(
pdcp_pP
->
kRRCint
,
kRRCint
+
16
,
16
)
:
memset
(
pdcp_pP
->
kRRCint
,
0
,
16
);
kUPenc
!=
NULL
?
memcpy
(
pdcp_pP
->
kUPenc
,
kUPenc
+
16
,
16
)
:
memset
(
pdcp_pP
->
kUPenc
,
0
,
16
);
pdcp_pP
->
security_container_rrc
=
stream_security_container_init
(
pdcp_pP
->
cipheringAlgorithm
,
pdcp_pP
->
integrityProtAlgorithm
,
pdcp_pP
->
kRRCenc
,
pdcp_pP
->
kRRCint
);
pdcp_pP
->
security_container_up
=
stream_security_container_init
(
pdcp_pP
->
cipheringAlgorithm
,
0
,
pdcp_pP
->
kUPenc
,
NULL
);
/* Activate security */
pdcp_pP
->
security_activated
=
1
;
...
...
@@ -2196,6 +2199,8 @@ void rrc_pdcp_config_req (
pdcp_p
->
last_submitted_pdcp_rx_sn
=
4095
;
pdcp_p
->
seq_num_size
=
0
;
pdcp_p
->
first_missing_pdu
=
-
1
;
stream_security_container_delete
(
pdcp_p
->
security_container_rrc
);
stream_security_container_delete
(
pdcp_p
->
security_container_up
);
pdcp_p
->
security_activated
=
0
;
h_rc
=
hashtable_remove
(
pdcp_coll_p
,
key
);
break
;
...
...
openair2/LAYER2/PDCP_v10.1.0/pdcp.h
View file @
252a7caf
...
...
@@ -181,9 +181,12 @@ typedef struct pdcp_s {
* Control-Plane RRC integrity key
* These keys are configured by RRC layer
*/
uint8_t
kUPenc
[
32
];
uint8_t
kRRCint
[
32
];
uint8_t
kRRCenc
[
32
];
uint8_t
kUPenc
[
16
];
uint8_t
kRRCint
[
16
];
uint8_t
kRRCenc
[
16
];
stream_security_container_t
*
security_container_rrc
;
stream_security_container_t
*
security_container_up
;
uint8_t
security_activated
;
...
...
openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c
View file @
252a7caf
...
...
@@ -112,6 +112,7 @@ pdcp_apply_security(
{
uint8_t
*
buffer_encrypted
=
NULL
;
nas_stream_cipher_t
encrypt_params
=
{
0
};
stream_security_container_t
*
container
;
DevAssert
(
pdcp_pP
!=
NULL
);
DevAssert
(
pdcp_pdu_buffer
!=
NULL
);
...
...
@@ -122,7 +123,11 @@ pdcp_apply_security(
encrypt_params
.
direction
=
(
pdcp_pP
->
is_ue
==
1
)
?
SECU_DIRECTION_UPLINK
:
SECU_DIRECTION_DOWNLINK
;
encrypt_params
.
bearer
=
rb_id
-
1
;
encrypt_params
.
count
=
pdcp_get_next_count_tx
(
pdcp_pP
,
srb_flagP
,
current_sn
);
encrypt_params
.
key_length
=
16
;
if
(
srb_flagP
)
container
=
pdcp_pP
->
security_container_rrc
;
else
container
=
pdcp_pP
->
security_container_up
;
if
(
srb_flagP
)
{
/* SRBs */
...
...
@@ -133,7 +138,7 @@ pdcp_apply_security(
encrypt_params
.
message
=
pdcp_pdu_buffer
;
encrypt_params
.
blength
=
(
pdcp_header_len
+
sdu_buffer_size
)
<<
3
;
encrypt_params
.
key
=
pdcp_pP
->
kRRCint
+
16
;
// + 128
;
encrypt_params
.
context
=
container
->
integrity_context
;
mac_i
=
&
pdcp_pdu_buffer
[
pdcp_header_len
+
sdu_buffer_size
];
...
...
@@ -142,15 +147,13 @@ pdcp_apply_security(
stream_compute_integrity
(
pdcp_pP
->
integrityProtAlgorithm
,
&
encrypt_params
,
mac_i
);
encrypt_params
.
key
=
pdcp_pP
->
kRRCenc
;
// + 128 // bit key
}
else
{
LOG_D
(
PDCP
,
"[OSA][RB %ld] %s Applying user-plane security
\n
"
,
rb_id
,
(
pdcp_pP
->
is_ue
!=
0
)
?
"UE -> eNB"
:
"eNB -> UE"
);
encrypt_params
.
key
=
pdcp_pP
->
kUPenc
;
// + 128;
}
encrypt_params
.
context
=
container
->
ciphering_context
;
encrypt_params
.
message
=
&
pdcp_pdu_buffer
[
pdcp_header_len
];
encrypt_params
.
blength
=
sdu_buffer_size
<<
3
;
...
...
@@ -180,6 +183,7 @@ pdcp_validate_security(
{
uint8_t
*
buffer_decrypted
=
NULL
;
nas_stream_cipher_t
decrypt_params
=
{
0
};
stream_security_container_t
*
container
;
DevAssert
(
pdcp_pP
!=
NULL
);
...
...
@@ -195,17 +199,17 @@ pdcp_validate_security(
decrypt_params
.
count
=
pdcp_get_next_count_rx
(
pdcp_pP
,
srb_flagP
,
hfn
,
sn
);
decrypt_params
.
message
=
&
pdcp_pdu_buffer
[
pdcp_header_len
];
decrypt_params
.
blength
=
(
sdu_buffer_size
-
pdcp_header_len
)
<<
3
;
decrypt_params
.
key_length
=
16
;
if
(
srb_flagP
)
{
LOG_D
(
PDCP
,
"[OSA][RB %ld] %s Validating control-plane security
\n
"
,
rb_id
,
(
pdcp_pP
->
is_ue
!=
0
)
?
"eNB -> UE"
:
"UE -> eNB"
);
decrypt_params
.
key
=
pdcp_pP
->
kRRCenc
;
// + 128
;
container
=
pdcp_pP
->
security_container_rrc
;
}
else
{
LOG_D
(
PDCP
,
"[OSA][RB %ld] %s Validating user-plane security
\n
"
,
rb_id
,
(
pdcp_pP
->
is_ue
!=
0
)
?
"eNB -> UE"
:
"UE -> eNB"
);
decrypt_params
.
key
=
pdcp_pP
->
kUPenc
;
// + 128
;
container
=
pdcp_pP
->
security_container_up
;
}
/* Uncipher the block */
decrypt_params
.
context
=
container
->
ciphering_context
;
stream_compute_encrypt
(
pdcp_pP
->
cipheringAlgorithm
,
&
decrypt_params
,
buffer_decrypted
);
if
(
!
IS_SOFTMODEM_IQPLAYER
)
{
...
...
@@ -213,7 +217,7 @@ pdcp_validate_security(
/* Now check the integrity of the complete PDU */
decrypt_params
.
message
=
pdcp_pdu_buffer
;
decrypt_params
.
blength
=
sdu_buffer_size
<<
3
;
decrypt_params
.
key
=
pdcp_pP
->
kRRCint
+
16
;
// 128
;
decrypt_params
.
context
=
container
->
integrity_context
;
if
(
pdcp_pP
->
integrityProtAlgorithm
!=
EIA0_ALG_ID
)
{
uint8_t
result
[
4
]
=
{
0
};
...
...
@@ -221,10 +225,9 @@ pdcp_validate_security(
if
(
memcmp
(
result
,
&
pdcp_pdu_buffer
[
sdu_buffer_size
],
4
)
!=
0
)
{
LOG_E
(
PDCP
,
"[OSA][RB %ld] %s failed to validate MAC-I
(key %llx)
of incoming PDU
\n
"
,
"[OSA][RB %ld] %s failed to validate MAC-I of incoming PDU
\n
"
,
rb_id
,
(
pdcp_pP
->
is_ue
!=
0
)
?
"UE"
:
"eNB"
,
((
long
long
unsigned
int
*
)
decrypt_params
.
key
)[
0
]);
(
pdcp_pP
->
is_ue
!=
0
)
?
"UE"
:
"eNB"
);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY
,
VCD_FUNCTION_OUT
);
return
-
1
;
}
...
...
openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h
View file @
252a7caf
...
...
@@ -28,6 +28,7 @@
#include "nr_pdcp_sdu.h"
#include "openair2/RRC/NR/rrc_gNB_radio_bearers.h"
#include "openair3/SECU/secu_defs.h"
/* PDCP Formats according to clause 6.2 of 3GPP TS 38.323 */
/* SN Size applicable to SRBs, UM DRBs and AM DRBs */
...
...
@@ -151,16 +152,17 @@ typedef struct nr_pdcp_entity_t {
int
integrity_algorithm
;
unsigned
char
ciphering_key
[
16
];
unsigned
char
integrity_key
[
16
];
void
*
security_context
;
void
(
*
cipher
)(
void
*
security_context
,
stream_security_context_t
*
security_context
;
void
(
*
cipher
)(
stream_security_context_t
*
security_context
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
);
void
(
*
free_security
)(
void
*
security_context
);
void
*
integrity_context
;
void
(
*
integrity
)(
void
*
integrity_context
,
unsigned
char
*
out
,
void
(
*
free_security
)(
stream_security_context_t
*
security_context
);
stream_security_context_t
*
integrity_context
;
void
(
*
integrity
)(
stream_security_context_t
*
integrity_context
,
unsigned
char
*
out
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
);
void
(
*
free_integrity
)(
void
*
integrity_context
);
void
(
*
free_integrity
)(
stream_security_context_t
*
integrity_context
);
/* security/integrity algorithms need to know uplink/downlink information
* which is reverse for gnb and ue, so we need to know if this
* pdcp entity is for a gnb or an ue
...
...
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.c
View file @
252a7caf
...
...
@@ -28,24 +28,23 @@
#include "openair3/SECU/secu_defs.h"
#include "openair3/SECU/key_nas_deriver.h"
void
*
nr_pdcp_integrity_nia1_init
(
unsigned
char
*
integrity_key
)
stream_security_context_t
*
nr_pdcp_integrity_nia1_init
(
unsigned
char
*
integrity_key
)
{
nas_stream_cipher_t
*
ret
;
ret
=
calloc
(
1
,
sizeof
(
*
ret
));
if
(
ret
==
NULL
)
abort
();
ret
->
key
=
malloc
(
16
);
if
(
ret
->
key
==
NULL
)
abort
();
memcpy
(
ret
->
key
,
integrity_key
,
16
);
ret
->
key_length
=
16
;
/* unused */
ret
->
context
=
malloc
(
16
);
if
(
ret
->
context
==
NULL
)
abort
();
memcpy
(
ret
->
context
,
integrity_key
,
16
);
return
ret
;
return
(
stream_security_context_t
*
)
ret
;
}
void
nr_pdcp_integrity_nia1_integrity
(
void
*
integrity_context
,
void
nr_pdcp_integrity_nia1_integrity
(
stream_security_context_t
*
integrity_context
,
unsigned
char
*
out
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
)
{
nas_stream_cipher_t
*
ctx
=
integrity_context
;
nas_stream_cipher_t
*
ctx
=
(
nas_stream_cipher_t
*
)
integrity_context
;
ctx
->
message
=
buffer
;
ctx
->
count
=
count
;
...
...
@@ -56,9 +55,9 @@ void nr_pdcp_integrity_nia1_integrity(void *integrity_context,
stream_compute_integrity
(
EIA1_128_ALG_ID
,
ctx
,
out
);
}
void
nr_pdcp_integrity_nia1_free_integrity
(
void
*
integrity_context
)
void
nr_pdcp_integrity_nia1_free_integrity
(
stream_security_context_t
*
integrity_context
)
{
nas_stream_cipher_t
*
ctx
=
integrity_context
;
free
(
ctx
->
key
);
nas_stream_cipher_t
*
ctx
=
(
nas_stream_cipher_t
*
)
integrity_context
;
free
(
ctx
->
context
);
free
(
ctx
);
}
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia1.h
View file @
252a7caf
...
...
@@ -22,13 +22,15 @@
#ifndef _NR_PDCP_INTEGRITY_NIA1_H_
#define _NR_PDCP_INTEGRITY_NIA1_H_
void
*
nr_pdcp_integrity_nia1_init
(
unsigned
char
*
integrity_key
);
#include "openair3/SECU/secu_defs.h"
void
nr_pdcp_integrity_nia1_integrity
(
void
*
integrity_context
,
stream_security_context_t
*
nr_pdcp_integrity_nia1_init
(
unsigned
char
*
integrity_key
);
void
nr_pdcp_integrity_nia1_integrity
(
stream_security_context_t
*
integrity_context
,
unsigned
char
*
out
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
);
void
nr_pdcp_integrity_nia1_free_integrity
(
void
*
integrity_context
);
void
nr_pdcp_integrity_nia1_free_integrity
(
stream_security_context_t
*
integrity_context
);
#endif
/* _NR_PDCP_INTEGRITY_NIA1_H_ */
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.c
View file @
252a7caf
...
...
@@ -30,29 +30,25 @@
#include "openair3/SECU/aes_128.h"
#include "openair3/SECU/aes_128_cbc_cmac.h"
void
*
nr_pdcp_integrity_nia2_init
(
uint8_t
integrity_key
[
16
])
stream_security_context_t
*
nr_pdcp_integrity_nia2_init
(
uint8_t
integrity_key
[
16
])
{
// This is a hack. Reduce the 3 functions to just cipher?
// No. The overhead is x8 times more. Don't change before measuring
// return integrity_key;
cbc_cmac_ctx_t
*
ctx
=
calloc
(
1
,
sizeof
(
cbc_cmac_ctx_t
));
AssertFatal
(
ctx
,
"Memory exhausted"
);
*
ctx
=
init_aes_128_cbc_cmac
(
integrity_key
);
return
ctx
;
return
(
stream_security_context_t
*
)
ctx
;
}
void
nr_pdcp_integrity_nia2_integrity
(
void
*
integrity_context
,
unsigned
char
*
out
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
)
void
nr_pdcp_integrity_nia2_integrity
(
stream_security_context_t
*
integrity_context
,
unsigned
char
*
out
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
)
{
DevAssert
(
integrity_context
!=
NULL
);
DevAssert
(
out
!=
NULL
);
DevAssert
(
buffer
!=
NULL
);
DevAssert
(
length
>
-
1
);
// Strange range: [1-32] instead of [0-31]
DevAssert
(
bearer
>
0
&&
bearer
<
33
);
DevAssert
(
count
>
-
1
);
cbc_cmac_ctx_t
*
ctx
=
(
cbc_cmac_ctx_t
*
)
integrity_context
;
cbc_cmac_ctx_t
*
ctx
=
(
cbc_cmac_ctx_t
*
)
integrity_context
;
aes_128_t
k_iv
=
{
0
};
memcpy
(
&
k_iv
.
key
,
ctx
->
key
,
sizeof
(
k_iv
.
key
));
...
...
@@ -64,18 +60,13 @@ void nr_pdcp_integrity_nia2_integrity(void *integrity_context, unsigned char *ou
uint8_t
result
[
16
]
=
{
0
};
byte_array_t
msg
=
{.
buf
=
buffer
,
.
len
=
length
};
cipher_aes_128_cbc_cmac
((
cbc_cmac_ctx_t
*
)
integrity_context
,
&
k_iv
,
msg
,
sizeof
(
result
),
result
);
//aes_128_cbc_cmac(&k_iv, msg, sizeof(result), result);
cipher_aes_128_cbc_cmac
(
ctx
,
&
k_iv
,
msg
,
sizeof
(
result
),
result
);
// AES CMAC (RFC 4493) outputs 128 bits but NR PDCP PDUs have a MAC-I of
// 32 bits (see 38.323 6.2). RFC 4493 2.1 says to truncate most significant
// bit first (so seems to say 33.401 B.2.3)
// Precondition: out should have enough space...
memcpy
(
out
,
result
,
4
);
}
void
nr_pdcp_integrity_nia2_free_integrity
(
void
*
integrity_context
)
void
nr_pdcp_integrity_nia2_free_integrity
(
stream_security_context_t
*
integrity_context
)
{
free
(
(
cbc_cmac_ctx_t
*
)
integrity_context
);
free_aes_128_cbc_cmac
((
cbc_cmac_ctx_t
*
)
integrity_context
);
free
(
integrity_context
);
}
openair2/LAYER2/nr_pdcp/nr_pdcp_integrity_nia2.h
View file @
252a7caf
...
...
@@ -24,13 +24,15 @@
#include <stdint.h>
void
*
nr_pdcp_integrity_nia2_init
(
uint8_t
integrity_key
[
16
]);
#include "openair3/SECU/secu_defs.h"
void
nr_pdcp_integrity_nia2_integrity
(
void
*
integrity_context
,
stream_security_context_t
*
nr_pdcp_integrity_nia2_init
(
uint8_t
integrity_key
[
16
]);
void
nr_pdcp_integrity_nia2_integrity
(
stream_security_context_t
*
integrity_context
,
unsigned
char
*
out
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
);
void
nr_pdcp_integrity_nia2_free_integrity
(
void
*
integrity_context
);
void
nr_pdcp_integrity_nia2_free_integrity
(
stream_security_context_t
*
integrity_context
);
#endif
/* _NR_PDCP_INTEGRITY_NIA2_H_ */
openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.c
View file @
252a7caf
...
...
@@ -29,14 +29,14 @@
#include <stdlib.h>
#include <string.h>
void
*
nr_pdcp_security_nea2_init
(
unsigned
char
*
ciphering_key
)
stream_security_context_t
*
nr_pdcp_security_nea2_init
(
unsigned
char
*
ciphering_key
)
{
// This is a hack, IMO init, cipher and free functions should be reduced to cipher.
// Test show a ~10% more processing time
return
ciphering_key
;
return
(
stream_security_context_t
*
)
ciphering_key
;
}
void
nr_pdcp_security_nea2_cipher
(
void
*
security_context
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
)
void
nr_pdcp_security_nea2_cipher
(
stream_security_context_t
*
security_context
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
)
{
DevAssert
(
security_context
!=
NULL
);
DevAssert
(
buffer
!=
NULL
);
...
...
@@ -62,7 +62,7 @@ void nr_pdcp_security_nea2_cipher(void *security_context, unsigned char *buffer,
memcpy
(
buffer
,
out
,
length
);
}
void
nr_pdcp_security_nea2_free_security
(
void
*
security_context
)
void
nr_pdcp_security_nea2_free_security
(
stream_security_context_t
*
security_context
)
{
(
void
)
security_context
;
}
openair2/LAYER2/nr_pdcp/nr_pdcp_security_nea2.h
View file @
252a7caf
...
...
@@ -22,12 +22,14 @@
#ifndef _NR_PDCP_SECURITY_NEA2_H_
#define _NR_PDCP_SECURITY_NEA2_H_
void
*
nr_pdcp_security_nea2_init
(
unsigned
char
*
ciphering_key
);
#include "openair3/SECU/secu_defs.h"
void
nr_pdcp_security_nea2_cipher
(
void
*
security_context
,
stream_security_context_t
*
nr_pdcp_security_nea2_init
(
unsigned
char
*
ciphering_key
);
void
nr_pdcp_security_nea2_cipher
(
stream_security_context_t
*
security_context
,
unsigned
char
*
buffer
,
int
length
,
int
bearer
,
int
count
,
int
direction
);
void
nr_pdcp_security_nea2_free_security
(
void
*
security_context
);
void
nr_pdcp_security_nea2_free_security
(
stream_security_context_t
*
security_context
);
#endif
/* _NR_PDCP_SECURITY_NEA2_H_ */
openair3/NAS/COMMON/API/NETWORK/nas_message.c
View file @
252a7caf
...
...
@@ -1009,8 +1009,7 @@ static int _nas_message_decrypt(
(
direction
==
SECU_DIRECTION_UPLINK
)
?
"UPLINK"
:
"DOWNLINK"
,
(
direction
==
SECU_DIRECTION_UPLINK
)
?
emm_security_context
->
ul_count
.
seq_num
:
emm_security_context
->
dl_count
.
seq_num
,
count
);
stream_cipher
.
key
=
emm_security_context
->
knas_enc
.
value
;
stream_cipher
.
key_length
=
AUTH_KNAS_ENC_SIZE
;
stream_cipher
.
context
=
emm_security_context
->
security_container
->
ciphering_context
;
stream_cipher
.
count
=
count
;
stream_cipher
.
bearer
=
0x00
;
//33.401 section 8.1.1
stream_cipher
.
direction
=
direction
;
...
...
@@ -1045,15 +1044,14 @@ static int _nas_message_decrypt(
(
direction
==
SECU_DIRECTION_UPLINK
)
?
"UPLINK"
:
"DOWNLINK"
,
(
direction
==
SECU_DIRECTION_UPLINK
)
?
emm_security_context
->
ul_count
.
seq_num
:
emm_security_context
->
dl_count
.
seq_num
,
count
);
stream_cipher
.
key
=
emm_security_context
->
knas_enc
.
value
;
stream_cipher
.
key_length
=
AUTH_KNAS_ENC_SIZE
;
stream_cipher
.
context
=
emm_security_context
->
security_container
->
ciphering_context
;
stream_cipher
.
count
=
count
;
stream_cipher
.
bearer
=
0x00
;
//33.401 section 8.1.1
stream_cipher
.
direction
=
direction
;
stream_cipher
.
message
=
(
unsigned
char
*
)
src
;
/* length in bits */
stream_cipher
.
blength
=
length
<<
3
;
stream_compute_encrypt
(
EEA
1
_128_ALG_ID
,
&
stream_cipher
,
(
unsigned
char
*
)
dest
);
stream_compute_encrypt
(
EEA
2
_128_ALG_ID
,
&
stream_cipher
,
(
unsigned
char
*
)
dest
);
/* Decode the first octet (security header type or EPS bearer identity,
* and protocol discriminator) */
...
...
@@ -1178,8 +1176,7 @@ static int _nas_message_encrypt(
(
direction
==
SECU_DIRECTION_UPLINK
)
?
"UPLINK"
:
"DOWNLINK"
,
(
direction
==
SECU_DIRECTION_UPLINK
)
?
emm_security_context
->
ul_count
.
seq_num
:
emm_security_context
->
dl_count
.
seq_num
,
count
);
stream_cipher
.
key
=
emm_security_context
->
knas_enc
.
value
;
stream_cipher
.
key_length
=
AUTH_KNAS_ENC_SIZE
;
stream_cipher
.
context
=
emm_security_context
->
security_container
->
ciphering_context
;
stream_cipher
.
count
=
count
;
stream_cipher
.
bearer
=
0x00
;
//33.401 section 8.1.1
stream_cipher
.
direction
=
direction
;
...
...
@@ -1208,8 +1205,7 @@ static int _nas_message_encrypt(
(
direction
==
SECU_DIRECTION_UPLINK
)
?
"UPLINK"
:
"DOWNLINK"
,
(
direction
==
SECU_DIRECTION_UPLINK
)
?
emm_security_context
->
ul_count
.
seq_num
:
emm_security_context
->
dl_count
.
seq_num
,
count
);
stream_cipher
.
key
=
emm_security_context
->
knas_enc
.
value
;
stream_cipher
.
key_length
=
AUTH_KNAS_ENC_SIZE
;
stream_cipher
.
context
=
emm_security_context
->
security_container
->
ciphering_context
;
stream_cipher
.
count
=
count
;
stream_cipher
.
bearer
=
0x00
;
//33.401 section 8.1.1
stream_cipher
.
direction
=
direction
;
...
...
@@ -1347,8 +1343,7 @@ static uint32_t _nas_message_get_mac(
fflush
(
stderr
);
#endif
stream_cipher
.
key
=
emm_security_context
->
knas_int
.
value
;
stream_cipher
.
key_length
=
AUTH_KNAS_INT_SIZE
;
stream_cipher
.
context
=
emm_security_context
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
count
;
stream_cipher
.
bearer
=
0x00
;
//33.401 section 8.1.1
stream_cipher
.
direction
=
direction
;
...
...
@@ -1391,8 +1386,7 @@ static uint32_t _nas_message_get_mac(
(
direction
==
SECU_DIRECTION_UPLINK
)
?
emm_security_context
->
ul_count
.
seq_num
:
emm_security_context
->
dl_count
.
seq_num
,
count
);
stream_cipher
.
key
=
emm_security_context
->
knas_int
.
value
;
stream_cipher
.
key_length
=
AUTH_KNAS_INT_SIZE
;
stream_cipher
.
context
=
emm_security_context
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
count
;
stream_cipher
.
bearer
=
0x00
;
//33.401 section 8.1.1
stream_cipher
.
direction
=
direction
;
...
...
openair3/NAS/NR_UE/nr_nas_msg_sim.c
View file @
252a7caf
...
...
@@ -515,6 +515,10 @@ void generateIdentityResponse(as_nas_info_t *initialNasMsg, uint8_t identitytype
static
void
generateAuthenticationResp
(
nr_ue_nas_t
*
nas
,
as_nas_info_t
*
initialNasMsg
,
uint8_t
*
buf
)
{
derive_ue_keys
(
buf
,
nas
);
/* todo: as of now, nia2 is hardcoded in derive_ue_keys(), remove this hardcoding, use NAS signalling for getting proper algorithm */
/* todo: deal with ciphering for this stream_security_container_init() (handle ciphering in general) */
/* todo: stream_security_container_delete() is not called anywhere, deal with that */
nas
->
security_container
=
stream_security_container_init
(
0
,
2
/* hardcoded: nia2 */
,
NULL
,
nas
->
security
.
knas_int
);
OctetString
res
;
res
.
length
=
16
;
res
.
value
=
calloc
(
1
,
16
);
...
...
@@ -598,8 +602,7 @@ static void generateSecurityModeComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
initialNasMsg
->
length
=
security_header_len
+
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
+
security_header_len
),
size
-
security_header_len
);
stream_cipher
.
key
=
nas
->
security
.
knas_int
;
stream_cipher
.
key_length
=
16
;
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
mm_counter
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
...
...
@@ -699,8 +702,7 @@ static void generateRegistrationComplete(nr_ue_nas_t *nas, as_nas_info_t *initia
}
initialNasMsg
->
length
=
length
;
stream_cipher
.
key
=
nas
->
security
.
knas_int
;
stream_cipher
.
key_length
=
16
;
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
mm_counter
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
...
...
@@ -762,8 +764,7 @@ static void generateDeregistrationRequest(nr_ue_nas_t *nas, as_nas_info_t *initi
initialNasMsg
->
length
=
security_header_len
+
mm_msg_encode
(
&
sp_msg
->
plain
.
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
+
security_header_len
),
size
-
security_header_len
);
nas_stream_cipher_t
stream_cipher
=
{
.
key
=
nas
->
security
.
knas_int
,
.
key_length
=
16
,
.
context
=
nas
->
security_container
->
integrity_context
,
.
count
=
nas
->
security
.
mm_counter
++
,
.
bearer
=
1
,
.
direction
=
0
,
...
...
@@ -853,8 +854,7 @@ static void generatePduSessionEstablishRequest(nr_ue_nas_t *nas, as_nas_info_t *
initialNasMsg
->
length
=
security_header_len
+
mm_msg_encode
(
mm_msg
,
(
uint8_t
*
)(
initialNasMsg
->
data
+
security_header_len
),
size
-
security_header_len
);
stream_cipher
.
key
=
nas
->
security
.
knas_int
;
stream_cipher
.
key_length
=
16
;
stream_cipher
.
context
=
nas
->
security_container
->
integrity_context
;
stream_cipher
.
count
=
nas
->
security
.
mm_counter
++
;
stream_cipher
.
bearer
=
1
;
stream_cipher
.
direction
=
0
;
...
...
openair3/NAS/NR_UE/nr_nas_msg_sim.h
View file @
252a7caf
...
...
@@ -41,6 +41,7 @@
#include "as_message.h"
#include "FGSUplinkNasTransport.h"
#include <openair3/UICC/usim_interface.h>
#include "secu_defs.h"
#define PLAIN_5GS_MSG 0b0000
#define INTEGRITY_PROTECTED 0b0001
...
...
@@ -98,6 +99,7 @@ typedef struct {
typedef
struct
{
uicc_t
*
uicc
;
ue_sa_security_key_t
security
;
stream_security_container_t
*
security_container
;
Guti5GSMobileIdentity_t
*
guti
;
bool
termination_procedure
;
}
nr_ue_nas_t
;
...
...
openair3/NAS/UE/EMM/SecurityModeControl.c
View file @
252a7caf
...
...
@@ -258,6 +258,7 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
LOG_TRACE
(
INFO
,
"EMM-PROC - Update Current security context"
);
/* Release non-current security context */
stream_security_container_delete
(
user
->
emm_data
->
security
->
security_container
);
_security_release
(
user
->
emm_data
->
security
);
user
->
emm_data
->
security
=
user
->
emm_data
->
non_current
;
/* Reset the uplink NAS COUNT counter */
...
...
@@ -265,6 +266,12 @@ int emm_proc_security_mode_command(nas_user_t *user, int native_ksi, int ksi,
user
->
emm_data
->
security
->
ul_count
.
seq_num
=
0
;
/* Set new security context indicator */
security_context_is_new
=
true
;
/* create contexts */
user
->
emm_data
->
security
->
security_container
=
stream_security_container_init
(
seea
,
seia
,
user
->
emm_data
->
non_current
->
knas_enc
.
value
,
user
->
emm_data
->
non_current
->
knas_int
.
value
);
}
}
...
...
openair3/NAS/UE/EMM/emmData.h
View file @
252a7caf
...
...
@@ -42,6 +42,7 @@ Description Defines internal private data handled by EPS Mobility
#include "commonDef.h"
#include "networkDef.h"
#include "securityDef.h"
#include "openair3/SECU/secu_defs.h"
#include "OctetString.h"
#include "nas_timer.h"
...
...
@@ -138,6 +139,7 @@ typedef struct emm_security_context_s {
//OctetString ksgsn; /* SGSN security key (mapped context) */
OctetString
knas_enc
;
/* NAS cyphering key */
OctetString
knas_int
;
/* NAS integrity key */
stream_security_container_t
*
security_container
;
/* container for NAS security */
struct
count_s
{
uint32_t
spare
:
8
;
uint32_t
overflow
:
16
;
...
...
openair3/SECU/aes_128_cbc_cmac.c
View file @
252a7caf
...
...
@@ -31,101 +31,56 @@
// code for version 3.0 or greater
#include <openssl/core_names.h>
static
const
char
*
propq
=
NULL
;
void
aes_128_cbc_cmac
(
const
aes_128_t
*
k_iv
,
byte_array_t
msg
,
size_t
len_out
,
uint8_t
out
[
len_out
])
cbc_cmac_ctx_t
init_aes_128_cbc_cmac
(
const
uint8_t
key
[
16
])
{
OSSL_LIB_CTX
*
library_context
=
OSSL_LIB_CTX_new
();
DevAssert
(
library_context
!=
NULL
);
DevAssert
(
key
!=
NULL
);
/* Fetch the CMAC implementation */
EVP_MAC
*
mac
=
EVP_MAC_fetch
(
library_context
,
"CMAC"
,
propq
);
DevAssert
(
mac
!=
NULL
);
EVP_MAC
*
mac_implementation
=
EVP_MAC_fetch
(
NULL
,
"CMAC"
,
NULL
);
DevAssert
(
mac
_implementation
!=
NULL
);
/* Create a context for the CMAC operation */
EVP_MAC_CTX
*
m
ctx
=
EVP_MAC_CTX_new
(
mac
);
DevAssert
(
m
ctx
!=
NULL
);
EVP_MAC_CTX
*
m
ac_context
=
EVP_MAC_CTX_new
(
mac_implementation
);
DevAssert
(
m
ac_context
!=
NULL
);
// The underlying cipher to be used
cbc_cmac_ctx_t
ctx
=
{
.
mac_implementation
=
mac_implementation
,
.
mac_context
=
mac_context
};
memcpy
(
ctx
.
key
,
key
,
16
);
// The underlying cipher to be used
char
cipher_name
[]
=
"aes128"
;
OSSL_PARAM
params
[
2
]
=
{
0
};
params
[
0
]
=
OSSL_PARAM_construct_utf8_string
(
OSSL_MAC_PARAM_CIPHER
,
cipher_name
,
sizeof
(
cipher_name
));
params
[
1
]
=
OSSL_PARAM_construct_end
();
params
[
0
]
=
OSSL_PARAM_construct_utf8_string
(
OSSL_MAC_PARAM_CIPHER
,
cipher_name
,
sizeof
(
cipher_name
));
params
[
1
]
=
OSSL_PARAM_construct_end
();
/* Initialise the CMAC operation */
int
rc
=
EVP_MAC_init
(
mctx
,
k_iv
->
key
,
sizeof
(
k_iv
->
key
),
params
);
DevAssert
(
rc
!=
0
);
size_t
sz_iv
=
0
;
uint8_t
*
iv
=
NULL
;
if
(
k_iv
->
type
==
AES_INITIALIZATION_VECTOR_8
){
sz_iv
=
8
;
iv
=
(
uint8_t
*
)
k_iv
->
iv8
.
iv
;
}
else
if
(
k_iv
->
type
==
AES_INITIALIZATION_VECTOR_16
)
{
sz_iv
=
16
;
iv
=
(
uint8_t
*
)
k_iv
->
iv16
.
iv
;
}
else
{
DevAssert
(
0
!=
0
&&
"Unknwon Initialization vector"
);
}
/* Make one or more calls to process the data to be authenticated */
rc
=
EVP_MAC_update
(
mctx
,
iv
,
sz_iv
);
int
rc
=
EVP_MAC_init
(
mac_context
,
key
,
16
,
params
);
DevAssert
(
rc
!=
0
);
/* Make one or more calls to process the data to be authenticated */
rc
=
EVP_MAC_update
(
mctx
,
msg
.
buf
,
msg
.
len
);
DevAssert
(
rc
!=
0
);
/* Make a call to the final with a NULL buffer to get the length of the MAC */
size_t
out_len
=
0
;
rc
=
EVP_MAC_final
(
mctx
,
out
,
&
out_len
,
len_out
);
DevAssert
(
rc
!=
0
);
EVP_MAC_CTX_free
(
mctx
);
EVP_MAC_free
(
mac
);
OSSL_LIB_CTX_free
(
library_context
);
}
cbc_cmac_ctx_t
init_aes_128_cbc_cmac
(
uint8_t
key
[
16
])
{
DevAssert
(
key
!=
NULL
);
OSSL_LIB_CTX
*
library_context
=
OSSL_LIB_CTX_new
();
DevAssert
(
library_context
!=
NULL
);
/* Fetch the CMAC implementation */
EVP_MAC
*
mac
=
EVP_MAC_fetch
(
library_context
,
"CMAC"
,
propq
);
DevAssert
(
mac
!=
NULL
);
cbc_cmac_ctx_t
ctx
=
{.
lib_ctx
=
library_context
,
.
mac
=
mac
};
assert
(
16
==
sizeof
(
ctx
.
key
));
memcpy
(
ctx
.
key
,
key
,
16
);
return
ctx
;
return
ctx
;
}
void
cipher_aes_128_cbc_cmac
(
cbc_cmac_ctx_t
const
*
ctx
,
const
aes_128_t
*
k_iv
,
byte_array_t
msg
,
size_t
len_out
,
uint8_t
out
[
len_out
])
{
DevAssert
(
ctx
!=
NULL
);
DevAssert
(
k_iv
!=
NULL
);
/* Create a context for the CMAC operation */
EVP_MAC_CTX
*
mctx
=
EVP_MAC_CTX_new
(
ctx
->
mac
);
DevAssert
(
mctx
!=
NULL
);
// The underlying cipher to be used
char
cipher_name
[]
=
"aes128"
;
OSSL_PARAM
params
[
2
]
=
{
0
};
params
[
0
]
=
OSSL_PARAM_construct_utf8_string
(
OSSL_MAC_PARAM_CIPHER
,
cipher_name
,
sizeof
(
cipher_name
));
params
[
1
]
=
OSSL_PARAM_construct_end
();
/* Initialise the CMAC operation */
int
rc
=
EVP_MAC_init
(
mctx
,
k_iv
->
key
,
sizeof
(
k_iv
->
key
),
params
);
/* reset the CMAC */
/* There is a bug with version <= 3.0.2 of OpenSSL for which we must
* pass the key to reset. (Some Ubuntu version provide this version.)
* Passing the key has some impact on performance.
* todo: drop support for old versions of openssl.
*/
#if OPENSSL_VERSION_NUMBER <= 0x30000020
/* todo: when/if we remove this code, don't forget to check use of k_iv->key
* somewhere else in the codebase.
* If not used, remove from aes_128_t*
*/
int
rc
=
EVP_MAC_init
(
ctx
->
mac_context
,
k_iv
->
key
,
16
,
NULL
);
#else
int
rc
=
EVP_MAC_init
(
ctx
->
mac_context
,
NULL
,
0
,
NULL
);
#endif
DevAssert
(
rc
!=
0
);
size_t
sz_iv
=
0
;
...
...
@@ -141,74 +96,41 @@ void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, b
}
/* Make one or more calls to process the data to be authenticated */
rc
=
EVP_MAC_update
(
mctx
,
iv
,
sz_iv
);
rc
=
EVP_MAC_update
(
ctx
->
mac_context
,
iv
,
sz_iv
);
DevAssert
(
rc
!=
0
);
/* Make one or more calls to process the data to be authenticated */
rc
=
EVP_MAC_update
(
mctx
,
msg
.
buf
,
msg
.
len
);
rc
=
EVP_MAC_update
(
ctx
->
mac_context
,
msg
.
buf
,
msg
.
len
);
DevAssert
(
rc
!=
0
);
/* Make a call to the final with a NULL buffer to get the length of the MAC */
size_t
out_len
=
0
;
rc
=
EVP_MAC_final
(
mctx
,
out
,
&
out_len
,
len_out
);
rc
=
EVP_MAC_final
(
ctx
->
mac_context
,
out
,
&
out_len
,
len_out
);
DevAssert
(
rc
!=
0
);
EVP_MAC_CTX_free
(
mctx
);
}
void
free_aes_128_cbc_cmac
(
cbc_cmac_ctx_t
const
*
ctx
)
{
DevAssert
(
ctx
!=
NULL
);
EVP_MAC_
free
(
ctx
->
mac
);
OSSL_LIB_CTX_free
(
ctx
->
lib_ctx
);
EVP_MAC_
CTX_free
(
ctx
->
mac_context
);
EVP_MAC_free
(
ctx
->
mac_implementation
);
}
#else
// code for 1.1.x or lower
void
aes_128_cbc_cmac
(
const
aes_128_t
*
k_iv
,
byte_array_t
msg
,
size_t
len_out
,
uint8_t
out
[
len_out
])
{
DevAssert
(
k_iv
!=
NULL
);
CMAC_CTX
*
ctx
=
CMAC_CTX_new
();
DevAssert
(
ctx
!=
NULL
);
CMAC_Init
(
ctx
,
k_iv
->
key
,
sizeof
(
k_iv
->
key
),
EVP_aes_128_cbc
(),
NULL
);
size_t
sz_iv
=
0
;
uint8_t
*
iv
=
NULL
;
if
(
k_iv
->
type
==
AES_INITIALIZATION_VECTOR_8
){
sz_iv
=
8
;
iv
=
(
uint8_t
*
)
k_iv
->
iv8
.
iv
;
}
else
if
(
k_iv
->
type
==
AES_INITIALIZATION_VECTOR_16
)
{
sz_iv
=
16
;
iv
=
(
uint8_t
*
)
k_iv
->
iv16
.
iv
;
}
else
{
AssertFatal
(
0
!=
0
,
"Unknwon Initialization vector"
);
}
CMAC_Update
(
ctx
,
iv
,
sz_iv
);
CMAC_Update
(
ctx
,
msg
.
buf
,
msg
.
len
);
size_t
len_res
=
0
;
CMAC_Final
(
ctx
,
out
,
&
len_res
);
DevAssert
(
len_res
<=
len_out
);
CMAC_CTX_free
(
ctx
);
}
cbc_cmac_ctx_t
init_aes_128_cbc_cmac
(
uint8_t
key
[
16
])
cbc_cmac_ctx_t
init_aes_128_cbc_cmac
(
const
uint8_t
key
[
16
])
{
DevAssert
(
key
!=
NULL
);
cbc_cmac_ctx_t
ctx
=
{.
lib_ctx
=
NULL
,
.
mac
=
NULL
};
cbc_cmac_ctx_t
ctx
=
{.
mac_implementation
=
NULL
,
.
mac_context
=
NULL
};
ctx
.
mac
=
CMAC_CTX_new
();
DevAssert
(
ctx
.
mac
!=
NULL
);
ctx
.
mac
_context
=
CMAC_CTX_new
();
DevAssert
(
ctx
.
mac
_context
!=
NULL
);
//assert(16 == sizeof(ctx.key));
memcpy
(
ctx
.
key
,
key
,
16
);
//sizeof(ctx.key));
CMAC_Init
(
ctx
.
mac
,
ctx
.
key
,
16
,
EVP_aes_128_cbc
(),
NULL
);
CMAC_Init
(
ctx
.
mac
_context
,
ctx
.
key
,
16
,
EVP_aes_128_cbc
(),
NULL
);
return
ctx
;
}
...
...
@@ -218,11 +140,11 @@ void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, b
DevAssert
(
k_iv
!=
NULL
);
//From https://man.openbsd.org/CMAC_Init.3
//If ctx is already initialized, CMAC_Init() can be called again with key,
//cipher, and impl all set to NULL and key_len set to 0. In that case, any
//data already processed is discarded and ctx is re-initialized to start
//If ctx is already initialized, CMAC_Init() can be called again with key,
//cipher, and impl all set to NULL and key_len set to 0. In that case, any
//data already processed is discarded and ctx is re-initialized to start
//reading data anew.
CMAC_Init
(
ctx
->
mac
,
NULL
,
0
,
NULL
,
NULL
);
CMAC_Init
(
ctx
->
mac
_context
,
NULL
,
0
,
NULL
,
NULL
);
size_t
sz_iv
=
0
;
uint8_t
*
iv
=
NULL
;
...
...
@@ -236,19 +158,18 @@ void cipher_aes_128_cbc_cmac(cbc_cmac_ctx_t const* ctx, const aes_128_t* k_iv, b
AssertFatal
(
0
!=
0
,
"Unknwon Initialization vector"
);
}
CMAC_Update
(
ctx
->
mac
,
iv
,
sz_iv
);
CMAC_Update
(
ctx
->
mac
_context
,
iv
,
sz_iv
);
CMAC_Update
(
ctx
->
mac
,
msg
.
buf
,
msg
.
len
);
CMAC_Update
(
ctx
->
mac
_context
,
msg
.
buf
,
msg
.
len
);
size_t
len_res
=
0
;
CMAC_Final
(
ctx
->
mac
,
out
,
&
len_res
);
CMAC_Final
(
ctx
->
mac
_context
,
out
,
&
len_res
);
DevAssert
(
len_res
<=
len_out
);
}
void
free_aes_128_cbc_cmac
(
cbc_cmac_ctx_t
const
*
ctx
)
{
DevAssert
(
ctx
!=
NULL
);
CMAC_CTX_free
(
ctx
->
mac
);
CMAC_CTX_free
(
ctx
->
mac
_context
);
}
#endif
openair3/SECU/aes_128_cbc_cmac.h
View file @
252a7caf
...
...
@@ -31,17 +31,13 @@
#include <stdlib.h>
typedef
struct
{
void
*
lib_ctx
;
void
*
mac
;
void
*
mac_implementation
;
void
*
mac_context
;
uint8_t
key
[
16
];
}
cbc_cmac_ctx_t
;
void
aes_128_cbc_cmac
(
const
aes_128_t
*
k_iv
,
byte_array_t
msg
,
size_t
len_out
,
uint8_t
out
[
len_out
]);
cbc_cmac_ctx_t
init_aes_128_cbc_cmac
(
uint8_t
key
[
16
]);
cbc_cmac_ctx_t
init_aes_128_cbc_cmac
(
const
uint8_t
key
[
16
]);
void
cipher_aes_128_cbc_cmac
(
cbc_cmac_ctx_t
const
*
ctx
,
const
aes_128_t
*
k_iv
,
byte_array_t
msg
,
size_t
len_out
,
uint8_t
out
[
len_out
]);
void
free_aes_128_cbc_cmac
(
cbc_cmac_ctx_t
const
*
ctx
);
#endif
...
...
openair3/SECU/nas_stream_eea1.c
View file @
252a7caf
...
...
@@ -38,10 +38,9 @@ void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *
//uint32_t byte_length;
uint32_t
*
KS
;
uint32_t
K
[
4
],
IV
[
4
];
uint8_t
*
key
=
(
uint8_t
*
)
stream_cipher
->
context
;
DevAssert
(
stream_cipher
!=
NULL
);
DevAssert
(
stream_cipher
->
key
!=
NULL
);
DevAssert
(
stream_cipher
->
key_length
==
16
);
DevAssert
(
out
!=
NULL
);
n
=
(
stream_cipher
->
blength
+
31
)
/
32
;
...
...
@@ -50,22 +49,20 @@ void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *
memset
(
&
snow_3g_context
,
0
,
sizeof
(
snow_3g_context
));
/*Initialisation*/
/* Load the confidentiality key for SNOW 3G initialization as in section
3.4. */
memcpy
(
K
+
3
,
stream_cipher
->
key
+
0
,
4
);
/*K[3] = key[0]; we assume
/* Load the confidentiality key for SNOW 3G initialization as in section 3.4. */
memcpy
(
K
+
3
,
key
+
0
,
4
);
/*K[3] = key[0]; we assume
K[3]=key[0]||key[1]||...||key[31] , with key[0] the
* most important bit of key*/
memcpy
(
K
+
2
,
stream_cipher
->
key
+
4
,
4
);
/*K[2] = key[1];*/
memcpy
(
K
+
1
,
stream_cipher
->
key
+
8
,
4
);
/*K[1] = key[2];*/
memcpy
(
K
+
0
,
stream_cipher
->
key
+
12
,
4
);
/*K[0] = key[3]; we assume
K[0]=key[96]||key[97]||...||key[127] , with key[127] the
* least important bit of key*/
memcpy
(
K
+
2
,
key
+
4
,
4
);
/*K[2] = key[1];*/
memcpy
(
K
+
1
,
key
+
8
,
4
);
/*K[1] = key[2];*/
memcpy
(
K
+
0
,
key
+
12
,
4
);
/*K[0] = key[3]; we assume
*
K[0]=key[96]||key[97]||...||key[127] , with key[127] the
* least important bit of key*/
K
[
3
]
=
hton_int32
(
K
[
3
]);
K
[
2
]
=
hton_int32
(
K
[
2
]);
K
[
1
]
=
hton_int32
(
K
[
1
]);
K
[
0
]
=
hton_int32
(
K
[
0
]);
/* Prepare the initialization vector (IV) for SNOW 3G initialization as in
section 3.4. */
/* Prepare the initialization vector (IV) for SNOW 3G initialization as in section 3.4. */
IV
[
3
]
=
stream_cipher
->
count
;
IV
[
2
]
=
((((
uint32_t
)
stream_cipher
->
bearer
)
<<
3
)
|
((((
uint32_t
)
stream_cipher
->
direction
)
&
0x1
)
<<
2
))
<<
24
;
IV
[
1
]
=
IV
[
3
];
...
...
@@ -104,3 +101,16 @@ void nas_stream_encrypt_eea1(nas_stream_cipher_t const *stream_cipher, uint8_t *
out
[
ceil_index
-
1
]
=
stream_cipher
->
message
[
ceil_index
-
1
];
}
}
stream_security_context_t
*
stream_ciphering_init_eea1
(
const
uint8_t
*
ciphering_key
)
{
void
*
ret
=
calloc
(
1
,
16
);
AssertFatal
(
ret
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
ret
,
ciphering_key
,
16
);
return
(
stream_security_context_t
*
)
ret
;
}
void
stream_ciphering_free_eea1
(
stream_security_context_t
*
ciphering_context
)
{
free
(
ciphering_context
);
}
openair3/SECU/nas_stream_eea1.h
View file @
252a7caf
...
...
@@ -29,4 +29,7 @@
void
nas_stream_encrypt_eea1
(
nas_stream_cipher_t
const
*
stream_cipher
,
uint8_t
*
out
);
stream_security_context_t
*
stream_ciphering_init_eea1
(
const
uint8_t
*
ciphering_key
);
void
stream_ciphering_free_eea1
(
stream_security_context_t
*
ciphering_context
);
#endif
openair3/SECU/nas_stream_eea2.c
View file @
252a7caf
...
...
@@ -33,15 +33,13 @@
void
nas_stream_encrypt_eea2
(
nas_stream_cipher_t
const
*
stream_cipher
,
uint8_t
*
out
)
{
DevAssert
(
stream_cipher
!=
NULL
);
DevAssert
(
stream_cipher
->
key
!=
NULL
);
DevAssert
(
stream_cipher
->
key_length
==
32
);
DevAssert
(
stream_cipher
->
bearer
<
32
);
DevAssert
(
stream_cipher
->
direction
<
2
);
DevAssert
(
stream_cipher
->
message
!=
NULL
);
DevAssert
(
stream_cipher
->
blength
>
7
);
aes_128_t
p
=
{
0
};
memcpy
(
p
.
key
,
stream_cipher
->
key
,
stream_cipher
->
key_length
);
memcpy
(
p
.
key
,
stream_cipher
->
context
,
16
);
p
.
type
=
AES_INITIALIZATION_VECTOR_16
;
p
.
iv16
.
d
.
count
=
htonl
(
stream_cipher
->
count
);
p
.
iv16
.
d
.
bearer
=
stream_cipher
->
bearer
;
...
...
@@ -54,3 +52,16 @@ void nas_stream_encrypt_eea2(nas_stream_cipher_t const *stream_cipher, uint8_t *
byte_array_t
msg
=
{.
buf
=
stream_cipher
->
message
,
.
len
=
byte_lenght
};
aes_128_ctr
(
&
p
,
msg
,
len_out
,
out
);
}
stream_security_context_t
*
stream_ciphering_init_eea2
(
const
uint8_t
*
ciphering_key
)
{
void
*
ret
=
calloc
(
1
,
16
);
AssertFatal
(
ret
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
ret
,
ciphering_key
,
16
);
return
(
stream_security_context_t
*
)
ret
;
}
void
stream_ciphering_free_eea2
(
stream_security_context_t
*
ciphering_context
)
{
free
(
ciphering_context
);
}
openair3/SECU/nas_stream_eea2.h
View file @
252a7caf
...
...
@@ -26,40 +26,9 @@
#include "secu_defs.h"
#include <stdint.h>
/* Rijndael S-box OSA_SR */
static
const
uint8_t
OSA_SR
[
256
]
=
{
0x63
,
0x7C
,
0x77
,
0x7B
,
0xF2
,
0x6B
,
0x6F
,
0xC5
,
0x30
,
0x01
,
0x67
,
0x2B
,
0xFE
,
0xD7
,
0xAB
,
0x76
,
0xCA
,
0x82
,
0xC9
,
0x7D
,
0xFA
,
0x59
,
0x47
,
0xF0
,
0xAD
,
0xD4
,
0xA2
,
0xAF
,
0x9C
,
0xA4
,
0x72
,
0xC0
,
0xB7
,
0xFD
,
0x93
,
0x26
,
0x36
,
0x3F
,
0xF7
,
0xCC
,
0x34
,
0xA5
,
0xE5
,
0xF1
,
0x71
,
0xD8
,
0x31
,
0x15
,
0x04
,
0xC7
,
0x23
,
0xC3
,
0x18
,
0x96
,
0x05
,
0x9A
,
0x07
,
0x12
,
0x80
,
0xE2
,
0xEB
,
0x27
,
0xB2
,
0x75
,
0x09
,
0x83
,
0x2C
,
0x1A
,
0x1B
,
0x6E
,
0x5A
,
0xA0
,
0x52
,
0x3B
,
0xD6
,
0xB3
,
0x29
,
0xE3
,
0x2F
,
0x84
,
0x53
,
0xD1
,
0x00
,
0xED
,
0x20
,
0xFC
,
0xB1
,
0x5B
,
0x6A
,
0xCB
,
0xBE
,
0x39
,
0x4A
,
0x4C
,
0x58
,
0xCF
,
0xD0
,
0xEF
,
0xAA
,
0xFB
,
0x43
,
0x4D
,
0x33
,
0x85
,
0x45
,
0xF9
,
0x02
,
0x7F
,
0x50
,
0x3C
,
0x9F
,
0xA8
,
0x51
,
0xA3
,
0x40
,
0x8F
,
0x92
,
0x9D
,
0x38
,
0xF5
,
0xBC
,
0xB6
,
0xDA
,
0x21
,
0x10
,
0xFF
,
0xF3
,
0xD2
,
0xCD
,
0x0C
,
0x13
,
0xEC
,
0x5F
,
0x97
,
0x44
,
0x17
,
0xC4
,
0xA7
,
0x7E
,
0x3D
,
0x64
,
0x5D
,
0x19
,
0x73
,
0x60
,
0x81
,
0x4F
,
0xDC
,
0x22
,
0x2A
,
0x90
,
0x88
,
0x46
,
0xEE
,
0xB8
,
0x14
,
0xDE
,
0x5E
,
0x0B
,
0xDB
,
0xE0
,
0x32
,
0x3A
,
0x0A
,
0x49
,
0x06
,
0x24
,
0x5C
,
0xC2
,
0xD3
,
0xAC
,
0x62
,
0x91
,
0x95
,
0xE4
,
0x79
,
0xE7
,
0xC8
,
0x37
,
0x6D
,
0x8D
,
0xD5
,
0x4E
,
0xA9
,
0x6C
,
0x56
,
0xF4
,
0xEA
,
0x65
,
0x7A
,
0xAE
,
0x08
,
0xBA
,
0x78
,
0x25
,
0x2E
,
0x1C
,
0xA6
,
0xB4
,
0xC6
,
0xE8
,
0xDD
,
0x74
,
0x1F
,
0x4B
,
0xBD
,
0x8B
,
0x8A
,
0x70
,
0x3E
,
0xB5
,
0x66
,
0x48
,
0x03
,
0xF6
,
0x0E
,
0x61
,
0x35
,
0x57
,
0xB9
,
0x86
,
0xC1
,
0x1D
,
0x9E
,
0xE1
,
0xF8
,
0x98
,
0x11
,
0x69
,
0xD9
,
0x8E
,
0x94
,
0x9B
,
0x1E
,
0x87
,
0xE9
,
0xCE
,
0x55
,
0x28
,
0xDF
,
0x8C
,
0xA1
,
0x89
,
0x0D
,
0xBF
,
0xE6
,
0x42
,
0x68
,
0x41
,
0x99
,
0x2D
,
0x0F
,
0xB0
,
0x54
,
0xBB
,
0x16
};
/* S-box OSA_SQ */
static
const
uint8_t
OSA_SQ
[
256
]
=
{
0x25
,
0x24
,
0x73
,
0x67
,
0xD7
,
0xAE
,
0x5C
,
0x30
,
0xA4
,
0xEE
,
0x6E
,
0xCB
,
0x7D
,
0xB5
,
0x82
,
0xDB
,
0xE4
,
0x8E
,
0x48
,
0x49
,
0x4F
,
0x5D
,
0x6A
,
0x78
,
0x70
,
0x88
,
0xE8
,
0x5F
,
0x5E
,
0x84
,
0x65
,
0xE2
,
0xD8
,
0xE9
,
0xCC
,
0xED
,
0x40
,
0x2F
,
0x11
,
0x28
,
0x57
,
0xD2
,
0xAC
,
0xE3
,
0x4A
,
0x15
,
0x1B
,
0xB9
,
0xB2
,
0x80
,
0x85
,
0xA6
,
0x2E
,
0x02
,
0x47
,
0x29
,
0x07
,
0x4B
,
0x0E
,
0xC1
,
0x51
,
0xAA
,
0x89
,
0xD4
,
0xCA
,
0x01
,
0x46
,
0xB3
,
0xEF
,
0xDD
,
0x44
,
0x7B
,
0xC2
,
0x7F
,
0xBE
,
0xC3
,
0x9F
,
0x20
,
0x4C
,
0x64
,
0x83
,
0xA2
,
0x68
,
0x42
,
0x13
,
0xB4
,
0x41
,
0xCD
,
0xBA
,
0xC6
,
0xBB
,
0x6D
,
0x4D
,
0x71
,
0x21
,
0xF4
,
0x8D
,
0xB0
,
0xE5
,
0x93
,
0xFE
,
0x8F
,
0xE6
,
0xCF
,
0x43
,
0x45
,
0x31
,
0x22
,
0x37
,
0x36
,
0x96
,
0xFA
,
0xBC
,
0x0F
,
0x08
,
0x52
,
0x1D
,
0x55
,
0x1A
,
0xC5
,
0x4E
,
0x23
,
0x69
,
0x7A
,
0x92
,
0xFF
,
0x5B
,
0x5A
,
0xEB
,
0x9A
,
0x1C
,
0xA9
,
0xD1
,
0x7E
,
0x0D
,
0xFC
,
0x50
,
0x8A
,
0xB6
,
0x62
,
0xF5
,
0x0A
,
0xF8
,
0xDC
,
0x03
,
0x3C
,
0x0C
,
0x39
,
0xF1
,
0xB8
,
0xF3
,
0x3D
,
0xF2
,
0xD5
,
0x97
,
0x66
,
0x81
,
0x32
,
0xA0
,
0x00
,
0x06
,
0xCE
,
0xF6
,
0xEA
,
0xB7
,
0x17
,
0xF7
,
0x8C
,
0x79
,
0xD6
,
0xA7
,
0xBF
,
0x8B
,
0x3F
,
0x1F
,
0x53
,
0x63
,
0x75
,
0x35
,
0x2C
,
0x60
,
0xFD
,
0x27
,
0xD3
,
0x94
,
0xA5
,
0x7C
,
0xA1
,
0x05
,
0x58
,
0x2D
,
0xBD
,
0xD9
,
0xC7
,
0xAF
,
0x6B
,
0x54
,
0x0B
,
0xE0
,
0x38
,
0x04
,
0xC8
,
0x9D
,
0xE7
,
0x14
,
0xB1
,
0x87
,
0x9C
,
0xDF
,
0x6F
,
0xF9
,
0xDA
,
0x2A
,
0xC4
,
0x59
,
0x16
,
0x74
,
0x91
,
0xAB
,
0x26
,
0x61
,
0x76
,
0x34
,
0x2B
,
0xAD
,
0x99
,
0xFB
,
0x72
,
0xEC
,
0x33
,
0x12
,
0xDE
,
0x98
,
0x3B
,
0xC0
,
0x9B
,
0x3E
,
0x18
,
0x10
,
0x3A
,
0x56
,
0xE1
,
0x77
,
0xC9
,
0x1E
,
0x9E
,
0x95
,
0xA3
,
0x90
,
0x19
,
0xA8
,
0x6C
,
0x09
,
0xD0
,
0xF0
,
0x86
};
void
nas_stream_encrypt_eea2
(
nas_stream_cipher_t
const
*
stream_cipher
,
uint8_t
*
out
);
stream_security_context_t
*
stream_ciphering_init_eea2
(
const
uint8_t
*
ciphering_key
);
void
stream_ciphering_free_eea2
(
stream_security_context_t
*
ciphering_context
);
#endif
openair3/SECU/nas_stream_eia1.c
View file @
252a7caf
...
...
@@ -126,16 +126,17 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o
uint64_t
M_D_2
;
int
rem_bits
;
uint32_t
mask
=
0
;
uint32_t
*
message
;
uint32_t
*
message
;
uint8_t
*
key
=
(
uint8_t
*
)
stream_cipher
->
context
;
message
=
(
uint32_t
*
)
stream_cipher
->
message
;
/* To operate 32 bit message internally. */
/* Load the Integrity Key for SNOW3G initialization as in section 4.4. */
memcpy
(
K
+
3
,
stream_cipher
->
key
+
0
,
4
);
/*K[3] = key[0]; we assume
memcpy
(
K
+
3
,
key
+
0
,
4
);
/*K[3] = key[0]; we assume
K[3]=key[0]||key[1]||...||key[31] , with key[0] the
* most important bit of key*/
memcpy
(
K
+
2
,
stream_cipher
->
key
+
4
,
4
);
/*K[2] = key[1];*/
memcpy
(
K
+
1
,
stream_cipher
->
key
+
8
,
4
);
/*K[1] = key[2];*/
memcpy
(
K
+
0
,
stream_cipher
->
key
+
12
,
4
);
/*K[0] = key[3]; we assume
memcpy
(
K
+
2
,
key
+
4
,
4
);
/*K[2] = key[1];*/
memcpy
(
K
+
1
,
key
+
8
,
4
);
/*K[1] = key[2];*/
memcpy
(
K
+
0
,
key
+
12
,
4
);
/*K[0] = key[3]; we assume
K[0]=key[96]||key[97]||...||key[127] , with key[127] the
* least important bit of key*/
K
[
3
]
=
hton_int32
(
K
[
3
]);
...
...
@@ -213,3 +214,16 @@ void nas_stream_encrypt_eia1(nas_stream_cipher_t const *stream_cipher, uint8_t o
MAC_I
=
hton_int32
(
MAC_I
);
memcpy
(
out
,
&
MAC_I
,
4
);
}
stream_security_context_t
*
stream_integrity_init_eia1
(
const
uint8_t
*
integrity_key
)
{
void
*
ret
=
calloc
(
1
,
16
);
AssertFatal
(
ret
!=
NULL
,
"out of memory
\n
"
);
memcpy
(
ret
,
integrity_key
,
16
);
return
(
stream_security_context_t
*
)
ret
;
}
void
stream_integrity_free_eia1
(
stream_security_context_t
*
integrity_context
)
{
free
(
integrity_context
);
}
openair3/SECU/nas_stream_eia1.h
View file @
252a7caf
...
...
@@ -26,4 +26,7 @@
void
nas_stream_encrypt_eia1
(
nas_stream_cipher_t
const
*
stream_cipher
,
uint8_t
out
[
4
]);
stream_security_context_t
*
stream_integrity_init_eia1
(
const
uint8_t
*
integrity_key
);
void
stream_integrity_free_eia1
(
stream_security_context_t
*
integrity_context
);
#endif
openair3/SECU/nas_stream_eia2.c
View file @
252a7caf
...
...
@@ -45,11 +45,11 @@ void nas_stream_encrypt_eia2(nas_stream_cipher_t const *stream_cipher, uint8_t o
DevAssert
(
stream_cipher
!=
NULL
);
DevAssert
(
stream_cipher
->
message
!=
NULL
);
DevAssert
(
stream_cipher
->
bearer
<
32
);
DevAssert
(
stream_cipher
->
key_length
==
16
);
DevAssert
((
stream_cipher
->
blength
&
0x7
)
==
0
);
cbc_cmac_ctx_t
*
ctx
=
(
cbc_cmac_ctx_t
*
)
stream_cipher
->
context
;
aes_128_t
k_iv
=
{
0
};
memcpy
(
k_iv
.
key
,
stream_cipher
->
key
,
sizeof
(
k_iv
.
key
)
);
memcpy
(
&
k_iv
.
key
,
ctx
->
key
,
16
);
k_iv
.
type
=
AES_INITIALIZATION_VECTOR_8
;
k_iv
.
iv8
.
d
.
bearer
=
stream_cipher
->
bearer
;
k_iv
.
iv8
.
d
.
direction
=
stream_cipher
->
direction
;
...
...
@@ -58,8 +58,21 @@ void nas_stream_encrypt_eia2(nas_stream_cipher_t const *stream_cipher, uint8_t o
size_t
const
m_length
=
stream_cipher
->
blength
>>
3
;
uint8_t
result
[
16
]
=
{
0
};
byte_array_t
msg
=
{.
buf
=
stream_cipher
->
message
,
.
len
=
m_length
};
aes_128_cbc_cmac
(
&
k_iv
,
msg
,
sizeof
(
result
),
result
);
cipher_aes_128_cbc_cmac
(
ctx
,
&
k_iv
,
msg
,
sizeof
(
result
),
result
);
memcpy
(
out
,
result
,
4
);
}
stream_security_context_t
*
stream_integrity_init_eia2
(
const
uint8_t
*
integrity_key
)
{
cbc_cmac_ctx_t
*
ret
=
calloc
(
1
,
sizeof
(
cbc_cmac_ctx_t
));
AssertFatal
(
ret
!=
NULL
,
"out of memory
\n
"
);
*
ret
=
init_aes_128_cbc_cmac
(
integrity_key
);
return
(
stream_security_context_t
*
)
ret
;
}
void
stream_integrity_free_eia2
(
stream_security_context_t
*
integrity_context
)
{
free_aes_128_cbc_cmac
((
cbc_cmac_ctx_t
*
)
integrity_context
);
free
(
integrity_context
);
}
openair3/SECU/nas_stream_eia2.h
View file @
252a7caf
...
...
@@ -26,4 +26,7 @@
void
nas_stream_encrypt_eia2
(
nas_stream_cipher_t
const
*
stream_cipher
,
uint8_t
out
[
4
]);
stream_security_context_t
*
stream_integrity_init_eia2
(
const
uint8_t
*
integrity_key
);
void
stream_integrity_free_eia2
(
stream_security_context_t
*
integrity_context
);
#endif
openair3/SECU/secu_defs.c
View file @
252a7caf
...
...
@@ -64,3 +64,70 @@ void stream_compute_encrypt(eea_alg_id_e alg, nas_stream_cipher_t const* stream_
}
}
stream_security_context_t
*
stream_integrity_init
(
int
integrity_algorithm
,
const
uint8_t
*
integrity_key
)
{
switch
(
integrity_algorithm
)
{
case
EEA0_ALG_ID
:
return
NULL
;
case
EEA1_128_ALG_ID
:
return
stream_integrity_init_eia1
(
integrity_key
);
case
EEA2_128_ALG_ID
:
return
stream_integrity_init_eia2
(
integrity_key
);
default:
AssertFatal
(
0
,
"unsupported integrity algorithm
\n
"
);
}
}
void
stream_integrity_free
(
int
integrity_algorithm
,
stream_security_context_t
*
integrity_context
)
{
switch
(
integrity_algorithm
)
{
case
EEA0_ALG_ID
:
return
;
case
EEA1_128_ALG_ID
:
return
stream_integrity_free_eia1
(
integrity_context
);
case
EEA2_128_ALG_ID
:
return
stream_integrity_free_eia2
(
integrity_context
);
default:
AssertFatal
(
0
,
"unsupported integrity algorithm
\n
"
);
}
}
stream_security_context_t
*
stream_ciphering_init
(
int
ciphering_algorithm
,
const
uint8_t
*
ciphering_key
)
{
switch
(
ciphering_algorithm
)
{
case
EEA0_ALG_ID
:
return
NULL
;
case
EEA1_128_ALG_ID
:
return
stream_ciphering_init_eea1
(
ciphering_key
);
case
EEA2_128_ALG_ID
:
return
stream_ciphering_init_eea2
(
ciphering_key
);
default:
AssertFatal
(
0
,
"unsupported ciphering algorithm
\n
"
);
}
}
void
stream_ciphering_free
(
int
ciphering_algorithm
,
stream_security_context_t
*
ciphering_context
)
{
switch
(
ciphering_algorithm
)
{
case
EEA0_ALG_ID
:
return
;
case
EEA1_128_ALG_ID
:
return
stream_ciphering_free_eea1
(
ciphering_context
);
case
EEA2_128_ALG_ID
:
return
stream_ciphering_free_eea2
(
ciphering_context
);
default:
AssertFatal
(
0
,
"unsupported ciphering algorithm
\n
"
);
}
}
stream_security_container_t
*
stream_security_container_init
(
int
ciphering_algorithm
,
int
integrity_algorithm
,
const
uint8_t
*
ciphering_key
,
const
uint8_t
*
integrity_key
)
{
stream_security_container_t
*
container
=
calloc
(
1
,
sizeof
(
*
container
));
AssertFatal
(
container
!=
NULL
,
"out of memory
\n
"
);
container
->
integrity_algorithm
=
integrity_algorithm
;
container
->
ciphering_algorithm
=
ciphering_algorithm
;
container
->
integrity_context
=
stream_integrity_init
(
integrity_algorithm
,
integrity_key
);
container
->
ciphering_context
=
stream_ciphering_init
(
ciphering_algorithm
,
ciphering_key
);
return
container
;
}
void
stream_security_container_delete
(
stream_security_container_t
*
container
)
{
/* passing NULL is accepted */
if
(
container
==
NULL
)
return
;
stream_integrity_free
(
container
->
integrity_algorithm
,
container
->
integrity_context
);
stream_ciphering_free
(
container
->
ciphering_algorithm
,
container
->
ciphering_context
);
free
(
container
);
}
openair3/SECU/secu_defs.h
View file @
252a7caf
...
...
@@ -28,17 +28,46 @@
#define SECU_DIRECTION_UPLINK 0
#define SECU_DIRECTION_DOWNLINK 1
/* stream_security_context_t is an opaque structure.
* It is different for each integrity and ciphering algorithm in use.
* Defined as a struct to have compilation time type checking
* (the "context" field is never actually used).
*/
typedef
struct
{
void
*
context
;
}
stream_security_context_t
;
/* stream_security_container_t contains the current configuration
* of integrity and ciphering. It is used by PDCP and NAS.
*/
typedef
struct
{
uint8_t
*
key
;
uint32_t
key_length
;
int
integrity_algorithm
;
int
ciphering_algorithm
;
stream_security_context_t
*
ciphering_context
;
stream_security_context_t
*
integrity_context
;
}
stream_security_container_t
;
typedef
struct
{
stream_security_context_t
*
context
;
uint32_t
count
;
uint8_t
bearer
;
uint8_t
direction
;
uint8_t
*
message
;
/* length in bits */
uint32_t
blength
;
uint32_t
blength
;
}
nas_stream_cipher_t
;
stream_security_context_t
*
stream_integrity_init
(
int
integrity_algorithm
,
const
uint8_t
*
integrity_key
);
stream_security_context_t
*
stream_ciphering_init
(
int
ciphering_algorithm
,
const
uint8_t
*
ciphering_key
);
void
stream_integrity_free
(
int
integrity_algorithm
,
stream_security_context_t
*
integrity_context
);
void
stream_ciphering_free
(
int
ciphering_algorithm
,
stream_security_context_t
*
ciphering_context
);
stream_security_container_t
*
stream_security_container_init
(
int
ciphering_algorithm
,
int
integrity_algorithm
,
const
uint8_t
*
ciphering_key
,
const
uint8_t
*
integrity_key
);
void
stream_security_container_delete
(
stream_security_container_t
*
container
);
/*!
* @brief Encrypt/Decrypt a block of data based on the provided algorithm
* @param[in] algorithm Algorithm used to encrypt the data
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment