Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG UE
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
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
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
Michael Black
OpenXG UE
Commits
a6eea8ac
Commit
a6eea8ac
authored
Jul 16, 2014
by
Lionel Gauthier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
git-svn-id:
http://svn.eurecom.fr/openair4G/trunk@5517
818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent
03a947bb
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
250 additions
and
11 deletions
+250
-11
openair2/UTIL/OSA/osa_defs.h
openair2/UTIL/OSA/osa_defs.h
+3
-3
openair2/UTIL/OSA/osa_key_deriver.c
openair2/UTIL/OSA/osa_key_deriver.c
+5
-4
openair2/UTIL/OSA/osa_stream_eea.c
openair2/UTIL/OSA/osa_stream_eea.c
+71
-2
openair2/UTIL/OSA/osa_stream_eia.c
openair2/UTIL/OSA/osa_stream_eia.c
+171
-2
No files found.
openair2/UTIL/OSA/osa_defs.h
View file @
a6eea8ac
...
...
@@ -60,15 +60,15 @@ typedef enum {
UP_ENC_ALG
=
0x05
}
algorithm_type_dist_t
;
int
derive_keNB
(
const
uint8_t
kasme
[
32
],
const
uint32_t
nas_count
,
uint8_t
**
keNB
);
//
int derive_keNB(const uint8_t kasme[32], const uint32_t nas_count, uint8_t **keNB);
int
derive_key
(
algorithm_type_dist_t
nas_alg_type
,
uint8_t
nas_enc_alg_id
,
const
uint8_t
key
[
32
],
uint8_t
**
out
);
#define derive_key_nas_enc(aLGiD, kEY, kNAS) \
//
#define derive_key_nas_enc(aLGiD, kEY, kNAS) \
derive_key
(
NAS_ENC_ALG
,
aLGiD
,
kEY
,
kNAS
)
#define derive_key_nas_int(aLGiD, kEY, kNAS) \
//
#define derive_key_nas_int(aLGiD, kEY, kNAS) \
derive_key
(
NAS_INT_ALG
,
aLGiD
,
kEY
,
kNAS
)
#define derive_key_rrc_enc(aLGiD, kEY, kNAS) \
...
...
openair2/UTIL/OSA/osa_key_deriver.c
View file @
a6eea8ac
...
...
@@ -75,20 +75,20 @@ int derive_key(algorithm_type_dist_t alg_type, uint8_t alg_id,
return
0
;
}
/*
int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB)
{
uint8_t string[7];
/
* FC */
/
/ FC
string[0] = FC_KENB;
/
* P0 = Uplink NAS count */
/
/ P0 = Uplink NAS count
string[1] = (nas_count & 0xff000000) >> 24;
string[2] = (nas_count & 0x00ff0000) >> 16;
string[3] = (nas_count & 0x0000ff00) >> 8;
string[4] = (nas_count & 0x000000ff);
/
* Length of NAS count */
/
/ Length of NAS count
string[5] = 0x00;
string[6] = 0x04;
...
...
@@ -108,3 +108,4 @@ int derive_keNB(const uint8_t key[32], const uint32_t nas_count, uint8_t **keNB)
return 0;
}
*/
openair2/UTIL/OSA/osa_stream_eea.c
View file @
a6eea8ac
...
...
@@ -11,6 +11,7 @@
#include "assertions.h"
#include "osa_defs.h"
#include "osa_snow3g.h"
#include "osa_internal.h"
int
stream_encrypt_eea0
(
stream_cipher_t
*
stream_cipher
,
uint8_t
**
out
)
...
...
@@ -42,6 +43,75 @@ int stream_encrypt_eea0(stream_cipher_t *stream_cipher, uint8_t **out)
return
0
;
}
int
stream_encrypt_eea1
(
stream_cipher_t
*
stream_cipher
,
uint8_t
**
out
)
{
osa_snow_3g_context_t
snow_3g_context
;
int
n
;
int
i
=
0
;
uint32_t
zero_bit
=
0
;
uint32_t
byte_length
;
uint32_t
*
KS
;
uint32_t
K
[
4
],
IV
[
4
];
DevAssert
(
stream_cipher
!=
NULL
);
DevAssert
(
stream_cipher
->
key
!=
NULL
);
DevAssert
(
stream_cipher
->
key_length
==
16
);
DevAssert
(
out
!=
NULL
);
n
=
(
stream_cipher
->
blength
+
31
)
/
32
;
zero_bit
=
stream_cipher
->
blength
&
0x7
;
byte_length
=
stream_cipher
->
blength
>>
3
;
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
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*/
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. */
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
];
IV
[
0
]
=
IV
[
2
];
/* Run SNOW 3G algorithm to generate sequence of key stream bits KS*/
osa_snow3g_initialize
(
K
,
IV
,
&
snow_3g_context
);
KS
=
(
uint32_t
*
)
malloc
(
4
*
n
);
osa_snow3g_generate_key_stream
(
n
,(
uint32_t
*
)
KS
,
&
snow_3g_context
);
if
(
zero_bit
>
0
)
{
KS
[
n
-
1
]
=
KS
[
n
-
1
]
&
(
uint32_t
)(
0xFFFFFFFF
<<
(
8
-
zero_bit
));
}
for
(
i
=
0
;
i
<
n
;
i
++
)
{
KS
[
i
]
=
hton_int32
(
KS
[
i
]);
}
/* Exclusive-OR the input data with keystream to generate the output bit
stream */
for
(
i
=
0
;
i
<
n
*
4
;
i
++
)
{
stream_cipher
->
message
[
i
]
^=
*
(((
uint8_t
*
)
KS
)
+
i
);
}
if
(
zero_bit
>
0
)
{
int
ceil_index
=
(
stream_cipher
->
blength
+
7
)
>>
3
;
stream_cipher
->
message
[
ceil_index
-
1
]
=
stream_cipher
->
message
[
ceil_index
-
1
]
&
(
uint8_t
)(
0xFF
<<
(
8
-
zero_bit
));
}
free
(
KS
);
*
out
=
stream_cipher
->
message
;
return
0
;
}
int
stream_encrypt_eea2
(
stream_cipher_t
*
stream_cipher
,
uint8_t
**
out
)
{
uint8_t
m
[
16
];
...
...
@@ -129,8 +199,7 @@ int stream_encrypt(uint8_t algorithm, stream_cipher_t *stream_cipher, uint8_t **
if
(
algorithm
==
EEA0_ALG_ID
)
{
return
stream_encrypt_eea0
(
stream_cipher
,
out
);
}
else
if
(
algorithm
==
EEA1_128_ALG_ID
)
{
LOG_E
(
OSA
,
"SNOW-3G algorithms are currently not implemented for encryption
\n
"
);
return
-
1
;
return
stream_encrypt_eea1
(
stream_cipher
,
out
);
}
else
if
(
algorithm
==
EEA2_128_ALG_ID
)
{
return
stream_encrypt_eea2
(
stream_cipher
,
out
);
}
...
...
openair2/UTIL/OSA/osa_stream_eia.c
View file @
a6eea8ac
...
...
@@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#include "assertions.h"
...
...
@@ -12,13 +13,181 @@
#include "UTIL/LOG/log.h"
#include "osa_defs.h"
#include "osa_snow3g.h"
#include "osa_internal.h"
// see spec 3GPP Confidentiality and Integrity Algorithms UEA2&UIA2. Document 1: UEA2 and UIA2 Specification. Version 1.1
/* OSA_MUL64x.
* Input V: a 64-bit input.
* Input c: a 64-bit input.
* Output : a 64-bit output.
* A 64-bit memory is allocated which is to be freed by the calling
* function.
* See section 4.3.2 for details.
*/
uint64_t
OSA_MUL64x
(
uint64_t
V
,
uint64_t
c
)
{
if
(
V
&
0x8000000000000000
)
return
(
V
<<
1
)
^
c
;
else
return
V
<<
1
;
}
/* OSA_MUL64xPOW.
* Input V: a 64-bit input.
* Input i: a positive integer.
* Input c: a 64-bit input.
* Output : a 64-bit output.
* A 64-bit memory is allocated which is to be freed by the calling
function.
* See section 4.3.3 for details.
*/
uint64_t
OSA_MUL64xPOW
(
uint64_t
V
,
uint32_t
i
,
uint64_t
c
)
{
if
(
i
==
0
)
return
V
;
else
return
OSA_MUL64x
(
OSA_MUL64xPOW
(
V
,
i
-
1
,
c
)
,
c
);
}
/* OSA_MUL64.
* Input V: a 64-bit input.
* Input P: a 64-bit input.
* Input c: a 64-bit input.
* Output : a 64-bit output.
* A 64-bit memory is allocated which is to be freed by the calling
* function.
* See section 4.3.4 for details.
*/
uint64_t
OSA_MUL64
(
uint64_t
V
,
uint64_t
P
,
uint64_t
c
)
{
uint64_t
result
=
0
;
int
i
=
0
;
for
(
i
=
0
;
i
<
64
;
i
++
)
{
if
(
(
P
>>
i
)
&
0x1
)
result
^=
OSA_MUL64xPOW
(
V
,
i
,
c
);
}
return
result
;
}
/* osa_mask32bit.
* Input n: an integer in 1-32.
* Output : a 32 bit mask.
* Prepares a 32 bit mask with required number of 1 bits on the MSB side.
*/
uint32_t
osa_mask32bit
(
int
n
)
{
uint32_t
mask
=
0x0
;
if
(
n
%
32
==
0
)
return
0xffffffff
;
while
(
n
--
)
mask
=
(
mask
>>
1
)
^
0x80000000
;
return
mask
;
}
/*!
* @brief Create integrity cmac t for a given message.
* @param[in] stream_cipher Structure containing various variables to setup encoding
* @param[out] out For EIA2 the output string is 32 bits long
*/
int
stream_compute_integrity_eia1
(
stream_cipher_t
*
stream_cipher
,
uint8_t
out
[
4
])
{
osa_snow_3g_context_t
snow_3g_context
;
uint32_t
K
[
4
],
IV
[
4
],
z
[
5
];
int
i
=
0
,
D
;
uint32_t
MAC_I
=
0
;
uint64_t
EVAL
;
uint64_t
V
;
uint64_t
P
;
uint64_t
Q
;
uint64_t
c
;
uint64_t
M_D_2
;
int
rem_bits
;
uint32_t
mask
=
0
;
uint32_t
*
message
;
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
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*/
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 SNOW3G initialization as in
section 4.4. */
IV
[
3
]
=
(
uint32_t
)
stream_cipher
->
count
;
IV
[
2
]
=
((((
uint32_t
)
stream_cipher
->
bearer
)
&
0x0000001F
)
<<
27
);
IV
[
1
]
=
(
uint32_t
)(
stream_cipher
->
count
)
^
(
(
uint32_t
)(
stream_cipher
->
direction
)
<<
31
)
;
IV
[
0
]
=
((((
uint32_t
)
stream_cipher
->
bearer
)
&
0x0000001F
)
<<
27
)
^
((
uint32_t
)(
stream_cipher
->
direction
&
0x00000001
)
<<
15
);
//printf ("K:\n");
//hexprint(K, 16);
//printf ("K[0]:%08X\n",K[0]);
//printf ("K[1]:%08X\n",K[1]);
//printf ("K[2]:%08X\n",K[2]);
//printf ("K[3]:%08X\n",K[3]);
//printf ("IV:\n");
//hexprint(IV, 16);
//printf ("IV[0]:%08X\n",IV[0]);
//printf ("IV[1]:%08X\n",IV[1]);
//printf ("IV[2]:%08X\n",IV[2]);
//printf ("IV[3]:%08X\n",IV[3]);
z
[
0
]
=
z
[
1
]
=
z
[
2
]
=
z
[
3
]
=
z
[
4
]
=
0
;
/* Run SNOW 3G to produce 5 keystream words z_1, z_2, z_3, z_4 and z_5. */
osa_snow3g_initialize
(
K
,
IV
,
&
snow_3g_context
);
osa_snow3g_generate_key_stream
(
5
,
z
,
&
snow_3g_context
);
//printf ("z[0]:%08X\n",z[0]);
//printf ("z[1]:%08X\n",z[1]);
//printf ("z[2]:%08X\n",z[2]);
//printf ("z[3]:%08X\n",z[3]);
//printf ("z[4]:%08X\n",z[4]);
P
=
((
uint64_t
)
z
[
0
]
<<
32
)
|
(
uint64_t
)
z
[
1
];
Q
=
((
uint64_t
)
z
[
2
]
<<
32
)
|
(
uint64_t
)
z
[
3
];
//printf ("P:%16lX\n",P);
//printf ("Q:%16lX\n",Q);
/* Calculation */
D
=
ceil
(
stream_cipher
->
blength
/
64
.
0
)
+
1
;
//printf ("D:%d\n",D);
EVAL
=
0
;
c
=
0x1b
;
/* for 0 <= i <= D-3 */
for
(
i
=
0
;
i
<
D
-
2
;
i
++
)
{
V
=
EVAL
^
(
(
uint64_t
)
hton_int32
(
message
[
2
*
i
])
<<
32
|
(
uint64_t
)
hton_int32
(
message
[
2
*
i
+
1
])
);
EVAL
=
OSA_MUL64
(
V
,
P
,
c
);
//printf ("Mi: %16X %16X\tEVAL: %16lX\n",hton_int32(message[2*i]),hton_int32(message[2*i+1]), EVAL);
}
/* for D-2 */
rem_bits
=
stream_cipher
->
blength
%
64
;
if
(
rem_bits
==
0
)
rem_bits
=
64
;
mask
=
osa_mask32bit
(
rem_bits
%
32
);
if
(
rem_bits
>
32
)
{
M_D_2
=
(
(
uint64_t
)
hton_int32
(
message
[
2
*
(
D
-
2
)])
<<
32
)
|
(
uint64_t
)
(
hton_int32
(
message
[
2
*
(
D
-
2
)
+
1
])
&
mask
);
}
else
{
M_D_2
=
(
(
uint64_t
)
hton_int32
(
message
[
2
*
(
D
-
2
)])
&
mask
)
<<
32
;
}
V
=
EVAL
^
M_D_2
;
EVAL
=
OSA_MUL64
(
V
,
P
,
c
);
/* for D-1 */
EVAL
^=
stream_cipher
->
blength
;
/* Multiply by Q */
EVAL
=
OSA_MUL64
(
EVAL
,
Q
,
c
);
MAC_I
=
(
uint32_t
)(
EVAL
>>
32
)
^
z
[
4
];
//printf ("MAC_I:%16X\n",MAC_I);
MAC_I
=
hton_int32
(
MAC_I
);
memcpy
(
out
,
&
MAC_I
,
4
);
return
0
;
}
int
stream_compute_integrity_eia2
(
stream_cipher_t
*
stream_cipher
,
uint8_t
out
[
4
])
{
uint8_t
*
m
;
...
...
@@ -83,8 +252,8 @@ int stream_compute_integrity_eia2(stream_cipher_t *stream_cipher, uint8_t out[4]
int
stream_compute_integrity
(
uint8_t
algorithm
,
stream_cipher_t
*
stream_cipher
,
uint8_t
out
[
4
])
{
if
(
algorithm
==
EIA1_128_ALG_ID
)
{
LOG_
E
(
OSA
,
"SNOW-3G algorithms are currently not implement
ed for integrity
\n
"
);
return
-
1
;
LOG_
D
(
OSA
,
"EIA1 algorithm appli
ed for integrity
\n
"
);
return
stream_compute_integrity_eia1
(
stream_cipher
,
out
)
;
}
else
if
(
algorithm
==
EIA2_128_ALG_ID
)
{
LOG_D
(
OSA
,
"EIA2 algorithm applied for integrity
\n
"
);
return
stream_compute_integrity_eia2
(
stream_cipher
,
out
);
...
...
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