baseband-devel
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 2024 discussions
Hi All.
It's time Again!
This is the announcement for the next Osmocom Berlin meeting.
Tomorrow, 8pm @ CCC Berlin, Marienstr. 11, 10117 Berlin
There is no formal presentation scheduled for this meeting.
If you are interested to show up, feel free to do so. There is no
registration required. The meeting is free as in "free beer", despite
no actual free beer being around.
I am looking forward to see you there!
regards.
Philipp
1
0
hello LSX,
Thanks for your input
I am using sylvain/testing branch, and trx was compiled correctly
On Mon, Feb 24, 2014 at 8:31 AM, LSX <289039690(a)qq.com> wrote:
>
> 这个文章我测试过,到时测试的时候不是用的这个分支,是用的jolly/testing这个分支,能搜索到openbts,信号,但无法注册基站。我就搞到这一步。
>
>
> ------------------ Original ------------------
> *From:* "Hassan Mourad";
> *Date:* 2014年2月24日(星期一) 下午2:21
> *To:* "baseband-devel";
> *Subject:* Osmocom Trx with OpenBTS
>
> Hi Guys,
>
> So I was trying to use my osmocom phone as a transceiver for openBTS.
>
> I followed the procedures indicated in this link "
> bb.osmocom.org/trac/wiki/Software/Transceiver" and was able to
> successfully load trx.compalram.bin on the phone, connect openBTS to it and
> sync the clock to the strongest cell around
>
> I got the output attached from openBTS
>
> For some reason however when I search for the network I am unable to find
> it.
>
> I can not figure out what exactly is going on here and I was wondering if
> any one can help
>
> One thing to point out is that I was never able to set the below value to
> the suggested value as it was not in OpenBTSs configuration options. I am
> not sure if this has been deprecated or replaced by any other options
>
> GSM.CellSelection.Neighbors = (set to empty string)
>
>
> Any help would be appreciated
>
> Starting the system...
> ALERT 139961385809696 07:54:21.0 TRXManager.cpp:434:powerOff: POWEROFF
> failed with status -1
> 50
> 41
> 1
> <0012> l1ctl.c:351 Reset received: Starting sync.
> <0012> l1ctl.c:308 Sync acquired, wait for BCCH ...
> <0011> trx.c:190 TRX CLK Indication 2119409
> <0011> trx.c:190 TRX CLK Indication 2119460
> <0011> trx.c:190 TRX CLK Indication 2119511
> <0011> trx.c:190 TRX CLK Indication 2119562
> <0011> trx.c:190 TRX CLK Indication 2119613
> <0011> trx.c:190 TRX CLK Indication 2119664
> <0011> trx.c:190 TRX CLK Indication 2119715
> <0011> trx.c:190 TRX CLK Indication 2119766
> <0011> trx.c:190 TRX CLK Indication 2119817
> <0011> trx.c:190 TRX CLK Indication 2119868
> <0011> trx.c:190 TRX CLK Indication 2119919
> <0011> trx.c:190 TRX CLK Indication 2119970
> <0011> trx.c:190 TRX CLK Indication 2120021
> <0011> trx.c:190 TRX CLK Indication 2120072
> <0011> trx.c:190 TRX CLK Indication 2120123
> <0011> trx.c:190 TRX CLK Indication 2120174
> <0011> trx.c:190 TRX CLK Indication 2120225
> <0011> trx.c:190 TRX CLK Indication 2120276
> <0011> trx.c:190 TRX CLK Indication 2120327
> <0011> trx.c:190 TRX CLK Indication 2120378
> <0011> trx.c:419 TRX Control recv: |READFACTORY|sdrsn|
> <0011> trx.c:432 [!] No handlers found for command 'READFACTORY'. Empty
> response
> <0011> trx.c:220 TRX Control send: |RSP READFACTORY -1|
> ALERT 139961385809696 07:54:26.0 TRXManager.cpp:595:getFactoryCalibration:
> READFACTORY failed with status -1
> <0011> trx.c:419 TRX Control recv: |RXTUNE|899200|
> <0011> trx.c:331 Setting C0 ARFCN to 46 (GSM900)
> <0011> trx.c:220 TRX Control send: |RSP RXTUNE 0 899200|
> <0011> trx.c:419 TRX Control recv: |TXTUNE|944200|
> <0011> trx.c:220 TRX Control send: |RSP TXTUNE 0 944200|
> <0011> trx.c:419 TRX Control recv: |SETBSIC|2|
> <0011> trx.c:220 TRX Control send: |RSP SETBSIC 0|
> <0011> trx.c:419 TRX Control recv: |SETMAXDLY|4|
> <0011> trx.c:220 TRX Control send: |RSP SETMAXDLY 0 4|
> <0011> trx.c:419 TRX Control recv: |SETRXGAIN|0|
> <0011> trx.c:220 TRX Control send: |RSP SETRXGAIN 0 0|
> <0011> trx.c:419 TRX Control recv: |POWERON||
> <0011> trx.c:220 TRX Control send: |RSP POWERON 0|
> <0011> trx.c:419 TRX Control recv: |SETPOWER|0|
> <0011> trx.c:220 TRX Control send: |RSP SETPOWER 0 0|
> <0011> trx.c:419 TRX Control recv: |SETSLOT|0 5|
> <0011> trx.c:220 TRX Control send: |RSP SETSLOT 0 5|
> <0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
> <0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
> response
> <0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
> <0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
> <0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
> response
> <0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
> <0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
> <0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
> response
> <0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
> <0011> trx.c:512 TRX Data 2120429:0:0:a06a94a2530140e0502112a56884a0
> <0011> trx.c:512 TRX Data 2120430:0:0:118a5328040142e042a04a81a80600
> <0011> trx.c:512 TRX Data 2120431:0:0:51a9402542006075080182102042a0
> <0011> trx.c:512 TRX Data 2120432:0:0:4424400420400a65a8022052a07800
> <0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
> <0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
> response
> <0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
> <0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
> <0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
> response
> <0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
> <0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
> <0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
> response
> <0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
> <0011> trx.c:512 TRX Data 2120382:0:0:a05f550a04dd106a017d008015d020
> <0011> trx.c:512 TRX Data 2120383:0:0:2ebf548abbf502eaadd548aeff4400
> <0011> trx.c:512 TRX Data 2120388:0:0:a05f550a04dd106a017d008015d020
> <0011> trx.c:512 TRX Data 2120389:0:0:2ebf548abbf502eaadd548aeff4400
> <0011> trx.c:512 TRX Data 2120390:0:0:047d148847740a6517554000754020
> <0011> trx.c:512 TRX Data 2120391:0:0:44a3ef550a3af5716aabf512aae5d0
> <0011> trx.c:512 TRX Data 2120392:0:0:a05f550a04dd106a017d008015d020
> <0011> trx.c:512 TRX Data 2120393:0:0:2ebf548abbf502eaadd548aeff4400
> <0011> trx.c:512 TRX Data 2120394:0:0:047d148847740a6517554000754020
> <0011> trx.c:512 TRX Data 2120395:0:0:44a3ef550a3af5716aabf512aae5d0
> <0011> trx.c:512 TRX Data 2120384:0:0:047d148847740a6517554000754020
> <0011> trx.c:512 TRX Data 2120385:0:0:44a3ef550a3af5716aabf512aae5d0
> <0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
> <0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
> response
> <0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
> <0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
> <0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
> response
> <0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
> <0011> trx.c:512 TRX Data 2120398:0:0:811d500a01fd40e845d40284155020
> <0011> trx.c:512 TRX Data 2120399:0:0:abff40aafff4026bffd500aadd4080
> <0011> trx.c:512 TRX Data 2120400:0:0:01f5508115d50a651f510801755020
> <0011> trx.c:512 TRX Data 2120401:0:0:10aabdd500aefd7102ab75108bbd50
> 1393221266.065242 139961385809696:
> system ready
>
> 1393221266.065285 139961385809696:
> use the OpenBTSCLI utility to access CLI
>
> <0011> trx.c:190 TRX CLK Indication 2120429
> <0011> trx.c:512 TRX Data 2120520:0:0:c096d65290454478404e00a504f460
> <0011> trx.c:512 TRX Data 2120521:0:0:868be1626f34806bbab501039959f0
> <0011> trx.c:512 TRX Data 2120522:0:0:1dcd716a92124d6d017d44b88d80e0
> <0011> trx.c:512 TRX Data 2120523:0:0:b54b391645229df90a9295874176f0
> <0011> trx.c:512 TRX Data 2120524:0:0:c096d65290454478404e00a504f460
> <0011> trx.c:512 TRX Data 2120525:0:0:868be1626f34806bbab501039959f0
> <0011> trx.c:512 TRX Data 2120526:0:0:1dcd716a92124d6d017d44b88d80e0
> <0011> trx.c:512 TRX Data 2120527:0:0:b54b391645229df90a9295874176f0
> <0011> trx.c:512 TRX Data 2120571:0:0:c096d65290454478404e00a504f460
> <0011> trx.c:512 TRX Data 2120572:0:0:868be1626f34806bbab501039959f0
> <0011> trx.c:512 TRX Data 2120573:0:0:1dcd716a92124d6d017d44b88d80e0
> <0011> trx.c:512 TRX Data 2120574:0:0:b54b391645229df90a9295874176f0
> <0011> trx.c:512 TRX Data 2120473:0:0:c096d65290454478404e00a504f460
> <0011> trx.c:512 TRX Data 2120474:0:0:868be1626f34806bbab501039959f0
> <0011> trx.c:512 TRX Data 2120475:0:0:1dcd716a92124d6d017d44b88d80e0
> <0011> trx.c:512 TRX Data 2120476:0:0:b54b391645229df90a9295874176f0
> <0011> trx.c:512 TRX Data 2120480:0:0:82d854472b9d417c613c4347d79a20
> <0011> trx.c:512 TRX Data 2120481:0:0:4183fbb006f782fa8b53440fe87df0
> <0011> trx.c:512 TRX Data 2120482:0:0:272d65f8c01e98e20cba2298934190
>
>
>
> --
> Sincerely
> Hassan Mourad
>
--
Sincerely
Hassan Mourad
3
3
Hi Guys,
So I was trying to use my osmocom phone as a transceiver for openBTS.
I followed the procedures indicated in this link "
bb.osmocom.org/trac/wiki/Software/Transceiver" and was able to successfully
load trx.compalram.bin on the phone, connect openBTS to it and sync the
clock to the strongest cell around
I got the output attached from openBTS
For some reason however when I search for the network I am unable to find
it.
I can not figure out what exactly is going on here and I was wondering if
any one can help
One thing to point out is that I was never able to set the below value to
the suggested value as it was not in OpenBTSs configuration options. I am
not sure if this has been deprecated or replaced by any other options
GSM.CellSelection.Neighbors = (set to empty string)
Any help would be appreciated
Starting the system...
ALERT 139961385809696 07:54:21.0 TRXManager.cpp:434:powerOff: POWEROFF
failed with status -1
50
41
1
<0012> l1ctl.c:351 Reset received: Starting sync.
<0012> l1ctl.c:308 Sync acquired, wait for BCCH ...
<0011> trx.c:190 TRX CLK Indication 2119409
<0011> trx.c:190 TRX CLK Indication 2119460
<0011> trx.c:190 TRX CLK Indication 2119511
<0011> trx.c:190 TRX CLK Indication 2119562
<0011> trx.c:190 TRX CLK Indication 2119613
<0011> trx.c:190 TRX CLK Indication 2119664
<0011> trx.c:190 TRX CLK Indication 2119715
<0011> trx.c:190 TRX CLK Indication 2119766
<0011> trx.c:190 TRX CLK Indication 2119817
<0011> trx.c:190 TRX CLK Indication 2119868
<0011> trx.c:190 TRX CLK Indication 2119919
<0011> trx.c:190 TRX CLK Indication 2119970
<0011> trx.c:190 TRX CLK Indication 2120021
<0011> trx.c:190 TRX CLK Indication 2120072
<0011> trx.c:190 TRX CLK Indication 2120123
<0011> trx.c:190 TRX CLK Indication 2120174
<0011> trx.c:190 TRX CLK Indication 2120225
<0011> trx.c:190 TRX CLK Indication 2120276
<0011> trx.c:190 TRX CLK Indication 2120327
<0011> trx.c:190 TRX CLK Indication 2120378
<0011> trx.c:419 TRX Control recv: |READFACTORY|sdrsn|
<0011> trx.c:432 [!] No handlers found for command 'READFACTORY'. Empty
response
<0011> trx.c:220 TRX Control send: |RSP READFACTORY -1|
ALERT 139961385809696 07:54:26.0 TRXManager.cpp:595:getFactoryCalibration:
READFACTORY failed with status -1
<0011> trx.c:419 TRX Control recv: |RXTUNE|899200|
<0011> trx.c:331 Setting C0 ARFCN to 46 (GSM900)
<0011> trx.c:220 TRX Control send: |RSP RXTUNE 0 899200|
<0011> trx.c:419 TRX Control recv: |TXTUNE|944200|
<0011> trx.c:220 TRX Control send: |RSP TXTUNE 0 944200|
<0011> trx.c:419 TRX Control recv: |SETBSIC|2|
<0011> trx.c:220 TRX Control send: |RSP SETBSIC 0|
<0011> trx.c:419 TRX Control recv: |SETMAXDLY|4|
<0011> trx.c:220 TRX Control send: |RSP SETMAXDLY 0 4|
<0011> trx.c:419 TRX Control recv: |SETRXGAIN|0|
<0011> trx.c:220 TRX Control send: |RSP SETRXGAIN 0 0|
<0011> trx.c:419 TRX Control recv: |POWERON||
<0011> trx.c:220 TRX Control send: |RSP POWERON 0|
<0011> trx.c:419 TRX Control recv: |SETPOWER|0|
<0011> trx.c:220 TRX Control send: |RSP SETPOWER 0 0|
<0011> trx.c:419 TRX Control recv: |SETSLOT|0 5|
<0011> trx.c:220 TRX Control send: |RSP SETSLOT 0 5|
<0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
<0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
response
<0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
<0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
<0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
response
<0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
<0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
<0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
response
<0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
<0011> trx.c:512 TRX Data 2120429:0:0:a06a94a2530140e0502112a56884a0
<0011> trx.c:512 TRX Data 2120430:0:0:118a5328040142e042a04a81a80600
<0011> trx.c:512 TRX Data 2120431:0:0:51a9402542006075080182102042a0
<0011> trx.c:512 TRX Data 2120432:0:0:4424400420400a65a8022052a07800
<0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
<0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
response
<0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
<0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
<0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
response
<0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
<0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
<0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
response
<0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
<0011> trx.c:512 TRX Data 2120382:0:0:a05f550a04dd106a017d008015d020
<0011> trx.c:512 TRX Data 2120383:0:0:2ebf548abbf502eaadd548aeff4400
<0011> trx.c:512 TRX Data 2120388:0:0:a05f550a04dd106a017d008015d020
<0011> trx.c:512 TRX Data 2120389:0:0:2ebf548abbf502eaadd548aeff4400
<0011> trx.c:512 TRX Data 2120390:0:0:047d148847740a6517554000754020
<0011> trx.c:512 TRX Data 2120391:0:0:44a3ef550a3af5716aabf512aae5d0
<0011> trx.c:512 TRX Data 2120392:0:0:a05f550a04dd106a017d008015d020
<0011> trx.c:512 TRX Data 2120393:0:0:2ebf548abbf502eaadd548aeff4400
<0011> trx.c:512 TRX Data 2120394:0:0:047d148847740a6517554000754020
<0011> trx.c:512 TRX Data 2120395:0:0:44a3ef550a3af5716aabf512aae5d0
<0011> trx.c:512 TRX Data 2120384:0:0:047d148847740a6517554000754020
<0011> trx.c:512 TRX Data 2120385:0:0:44a3ef550a3af5716aabf512aae5d0
<0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
<0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
response
<0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
<0011> trx.c:419 TRX Control recv: |NOHANDOVER|0|
<0011> trx.c:432 [!] No handlers found for command 'NOHANDOVER'. Empty
response
<0011> trx.c:220 TRX Control send: |RSP NOHANDOVER -1|
<0011> trx.c:512 TRX Data 2120398:0:0:811d500a01fd40e845d40284155020
<0011> trx.c:512 TRX Data 2120399:0:0:abff40aafff4026bffd500aadd4080
<0011> trx.c:512 TRX Data 2120400:0:0:01f5508115d50a651f510801755020
<0011> trx.c:512 TRX Data 2120401:0:0:10aabdd500aefd7102ab75108bbd50
1393221266.065242 139961385809696:
system ready
1393221266.065285 139961385809696:
use the OpenBTSCLI utility to access CLI
<0011> trx.c:190 TRX CLK Indication 2120429
<0011> trx.c:512 TRX Data 2120520:0:0:c096d65290454478404e00a504f460
<0011> trx.c:512 TRX Data 2120521:0:0:868be1626f34806bbab501039959f0
<0011> trx.c:512 TRX Data 2120522:0:0:1dcd716a92124d6d017d44b88d80e0
<0011> trx.c:512 TRX Data 2120523:0:0:b54b391645229df90a9295874176f0
<0011> trx.c:512 TRX Data 2120524:0:0:c096d65290454478404e00a504f460
<0011> trx.c:512 TRX Data 2120525:0:0:868be1626f34806bbab501039959f0
<0011> trx.c:512 TRX Data 2120526:0:0:1dcd716a92124d6d017d44b88d80e0
<0011> trx.c:512 TRX Data 2120527:0:0:b54b391645229df90a9295874176f0
<0011> trx.c:512 TRX Data 2120571:0:0:c096d65290454478404e00a504f460
<0011> trx.c:512 TRX Data 2120572:0:0:868be1626f34806bbab501039959f0
<0011> trx.c:512 TRX Data 2120573:0:0:1dcd716a92124d6d017d44b88d80e0
<0011> trx.c:512 TRX Data 2120574:0:0:b54b391645229df90a9295874176f0
<0011> trx.c:512 TRX Data 2120473:0:0:c096d65290454478404e00a504f460
<0011> trx.c:512 TRX Data 2120474:0:0:868be1626f34806bbab501039959f0
<0011> trx.c:512 TRX Data 2120475:0:0:1dcd716a92124d6d017d44b88d80e0
<0011> trx.c:512 TRX Data 2120476:0:0:b54b391645229df90a9295874176f0
<0011> trx.c:512 TRX Data 2120480:0:0:82d854472b9d417c613c4347d79a20
<0011> trx.c:512 TRX Data 2120481:0:0:4183fbb006f782fa8b53440fe87df0
<0011> trx.c:512 TRX Data 2120482:0:0:272d65f8c01e98e20cba2298934190
--
Sincerely
Hassan Mourad
1
0
Hi all,
I am new on this open source community.
I am a looking for a "basic" open source code that would be compliant with the UMTS standard. By basic I mean, I would simply try to manipulate my RTL2832u-based DVB-T dongle (on a R-PI) to make it reaching let's say the neighborhood cell IDs plus their corresponding receive power.
Maybe I am stupid, but despite the time I have spent on the websites and while there is a lot of very interesting stuffs related to GSM/GPRS/LTE standards: I could not find anything compliant. Even AT command would sound good to me in a first time.
Thanks for your answers or even for any clue,
Cheers,
Sébastien
1
0
Hi Michael,
It is my intention to share an image and speed the process
up for other researchers interested in GSM attacks and building simulations
in their labs. At this time there are code changes I want to expand upon
before I do (predominantly cosmetic changes and making it more feature
useful from the python script). I am also hoping that enhanced detection of
fakeBTS attacks will be expanded upon by the osmocom-bb toolkit (the launch
of the detection capability occurred in December 2013 at CCC.) which would
sufficiently detect anyone attempting to use tools of this nature in an
illegal way. Most of the work I did can be recreated from the slides
previously provided. If you are interested in the E100 platform, I spent
alot of time exploring its capabilities and re-compiling packages. I first
started trying to build the firmware from scratch with some discussion
occurring between myself and the firmware developer at Ettus, eventually it
became easier to customize the firmware provided by Ettus - the most
difficult change being a cross-compiled kernel to enable netfilter so that
IP routing became practical thus allowing for GPRS capabilities. I also had
issues with the OpenBTS 52MTransceiver application in the more recent
commits as significant overhaul has begun on changing its capabilities. I
eventually settled on r6718 version as this provided GPRS capabilities and
also was the last version functioning with the 52MTransceiver application.
Most of the firmware I had to rebuild from source including things not
available in package repos such as libpcap, asterisk (w/ODBC), odbc,
libsqlite and python to get the capabilities I needed to demonstrate the
practical elements of a GSM attack from an embedded device. I will be
releasing the firmware image as soon as I tidy up some of my python code
and detection tools become more effective. If you do really need the image
for some research purpose then please e-mail me directly and I will gladly
share a copy with you providing I can understand better your requirement
for needing an off-the-shelf attack tool for GSM.
Kind Regards,
Matthew
On Fri, Feb 14, 2014 at 3:53 PM, Michael Mooradian <
mooradianm(a)nkiengineering.com> wrote:
> Mathew,
>
> Is there any chance you will post the GreedyBTS E100 image online, or
> maybe even a screen capture demonstration of it working? I am very
> interested in how you were able to handle making the E100 run more
> efficiently. Also impressive is how you were able to script some very
> useful commands into your shell script. I would be very interested in how
> you were able to group all of it together.
>
> Thank you for any feedback you can give,
>
> Michael
>
>
> On Fri, Feb 7, 2014 at 5:12 AM, Hacker Fantastic <
> hackerfantastic(a)googlemail.com> wrote:
>
>> Hi all,
>> My first attempt to send this email didn't appear to succeed so I
>> am re-sending without attachment. Here is a copy of some slides
>> https://github.com/HackerFantastic/Public/blob/master/presentations/mwri_la… wrote for a presentation on security weaknesses within GSM. I used an
>> Ettus E100 to develop a malicious BTS and GSM related attacks in a Faraday
>> cage and presented on how these attacks work to better understand them for
>> defensive purposes. I was able to use the E100 as a generic IP-router after
>> I cross-compiled a new kernel with netfilter enabled and also I had to
>> recompile a number of the packages such as Asterisk to enable ODBC and
>> improved SQLite support, I also had to make some changes to Python and its
>> modules. I used GNURadio 3.6.4 and I had to compile a specific version of
>> the OpenBTS code as the recent transceiver application did not function
>> with the E100. I was able to get the E100 to work as a GSM/GPRS router and
>> do real-time call placement etc. I got it to function with real-time
>> support and wrote a small script to provision new devices by watching the
>> syslog and adding to the SQLite database.
>>
>> I also used osmocom-bb to do things like use gnuplot and graph the
>> channel usage although the code is extremely ugly! I took RSSI measurements
>> over a period of time into images and then tied them together for a movie,
>> it isn't quite realtime but it makes pretty graphs. I mentioned how you
>> could implement the MS side of the GSM stack using the osmocom project and
>> as such am sharing the slides with the osmocom list.
>>
>> Just goes to show how mighty things come in small packages! Hope this
>> material is useful to others on the list who may also be trying similar
>> experiments. I ended up creating a firmware image that could be used to dd
>> and boot an E100 but at this time I do not plan on hosting it for download
>> unless there is sufficient interest. If you need it for some reason drop me
>> an e-mail.
>>
>> Here is an example of the output of the greedyBTS script. As an example
>> my code plays "Rick Astley - never going to give you up" when a user places
>> a phone call and they have been provisioned with service. All of this work
>> was done in a faraday cage which I obtained from Ramsey electronics which
>> had very good frequency attenuation graph from 0mhz all the way to 1ghz.
>>
>> root@usrp-e1xx:~# ./launch.sh
>> Launching asterisk
>> Launching HLR SMS
>> Launching OpenBTS
>> Launching Greedy BTS..
>>
>> 888 888 d8
>> e88 888 888,8, ,e e, ,e e, e88 888 Y8b Y888P 888 88e d88 dP"Y
>> d888 888 888 " d88 88b d88 88b d888 888 Y8b Y8P 888 888b d88888 C88b
>> Y888 888 888 888 , 888 , Y888 888 Y8b Y 888 888P 888 Y88D
>> "88 888 888 "YeeP" "YeeP" "88 888 888 888 88" 888 d,dP
>> , 88P 888 pDK++
>>
>> "8",P" 888
>>
>>
>> [+] Current CELL configuration
>> [-] ==========================
>> [-] Shortname: 'Noone'
>> [-] MCC: 901 MNC: 70 C0 ARFCN: 51
>> [-] LAC: 3336 ARFCN's: 1 BAND: 900
>> [-]
>> [-] Radio Power
>> [-] ===========
>> [-] RxGain: 47 MaxPower: 10 MinPower: 0
>>
>> --> help
>>
>> [+] HELP SCREEN
>>
>> [-] dump imei - lists all identified IMEI
>>
>> [-] dump assoc - lists all IMEI+IMSI associations
>>
>> [-] dump imsi - lists all identified IMSI
>>
>> [-] dump save - store a record of all identities
>>
>> [-] start service - provide service to IMSI & log traffic
>>
>> [-] show service - show all provisioned phones
>>
>> [-] stop service - deletes an identified IMSI from HLR
>>
>> [-] calls - provide call collection statistics
>>
>> [-] sms - provide sms collection statistics
>>
>> [!] gprs - provide gprs collection statistics
>>
>> [-] cellconfig - configure cell parameters for spoofing
>>
>> [-] cellinfo - dump information on current cell
>>
>> [-] cellshow - list short codes for common cells
>>
>> [!] sounddial - play a sound recording to an IMSI
>>
>> [!] spoofsms - send a spoof SMS message to an IMSI
>>
>> [!] trunksetup - display current SIP trunk details
>>
>> [-] verbose - turn on real time tracing
>>
>> [-] exit - leave without shutdown
>>
>> [-] shutdown - bye!
>>
>> --> dump imei
>>
>> [+] Dumping seen handset IMEI
>>
>> [-] 1: IMEI359209002648230
>>
>> [-] 2: IMEI358622002760070
>>
>> [-] 3: IMEI350694801239040
>>
>> [-] Total IMEI identified 3
>>
>> --> dump imsi
>>
>> [+] Dumping IMSI capture results
>>
>> [-] 1: IMSI901700000002484
>>
>> [-] 2: IMSI901700000002486
>>
>> [-] 3: IMSI901700000002488
>>
>> [-] Total IMSI identified 3
>>
>> --> dump assoc
>>
>> [+] Dumping IMSI/IMEI association
>>
>> [-] 1 IMEI:358622002760070 used IMSI901700000002486
>>
>> [-] 2 IMEI:350694801239040 used IMSI901700000002488
>>
>> [-] Total associations 2
>>
>> --> show service
>>
>> [+] Displaying all provisioned IMSI
>>
>> [-] 1: exten: 2100 user: IMSI001010000000000
>>
>> [-] 2: exten: 2339 user: IMSI901700000002484
>>
>> [-] Total subscriber count 2
>>
>> --> stop service
>>
>> [+] Deleting IMSI from HLR
>>
>> [-] Enter IMSI: IMSI901700000002484
>>
>> [-] Deleted IMSI901700000002484
>>
>> --> help
>>
>> [+] HELP SCREEN
>>
>> [-] dump imei - lists all identified IMEI
>>
>> [-] dump assoc - lists all IMEI+IMSI associations
>>
>> [-] dump imsi - lists all identified IMSI
>>
>> [-] dump save - store a record of all identities
>>
>> [-] start service - provide service to IMSI & log traffic
>>
>> [-] show service - show all provisioned phones
>>
>> [-] stop service - deletes an identified IMSI from HLR
>>
>> [-] calls - provide call collection statistics
>>
>> [-] sms - provide sms collection statistics
>>
>> [!] gprs - provide gprs collection statistics
>>
>> [-] cellconfig - configure cell parameters for spoofing
>>
>> [-] cellinfo - dump information on current cell
>>
>> [-] cellshow - list short codes for common cells
>>
>> [!] sounddial - play a sound recording to an IMSI
>>
>> [!] spoofsms - send a spoof SMS message to an IMSI
>>
>> [!] trunksetup - display current SIP trunk details
>>
>> [-] verbose - turn on real time tracing
>>
>> [-] exit - leave without shutdown
>>
>> [-] shutdown - bye!
>>
>> --> dump imei
>>
>> [+] Dumping seen handset IMEI
>>
>> [-] 1: IMEI359209002648230
>>
>> [-] 2: IMEI358622002760070
>>
>> [-] 3: IMEI350694801239040
>>
>> [-] Total IMEI identified 3
>>
>> --> dump imsi
>>
>> [+] Dumping IMSI capture results
>>
>> [-] 1: IMSI901700000002484
>>
>> [-] 2: IMSI901700000002486
>>
>> [-] 3: IMSI901700000002488
>>
>> [-] Total IMSI identified 3
>>
>> --> dump assoc
>>
>> [+] Dumping IMSI/IMEI association
>>
>> [-] 1 IMEI:358622002760070 used IMSI901700000002486
>>
>> [-] 2 IMEI:350694801239040 used IMSI901700000002488
>>
>> [-] Total associations 2
>>
>> --> dump save
>>
>> [+] Saving IMSI capture results
>>
>> [+] Saving seen handset IMEI
>>
>> [+] Saving IMSI/IMEI association
>>
>> [-] logfile stored as 'greedybts.log'
>>
>> --> shutdown
>>
>> root@usrp-e1xx:~# cat greedybts.log
>>
>> [-] 1: IMSI901700000002484
>>
>> [-] 2: IMSI901700000002486
>>
>> [-] 3: IMSI901700000002488
>>
>> [-] Total IMSI identified 3
>>
>> [-] 1: IMEI359209002648230
>>
>> [-] 2: IMEI358622002760070
>>
>> [-] 3: IMEI350694801239040
>>
>> [-] Total IMEI identified 3
>>
>> [-] 1 IMEI:358622002760070 used IMSI901700000002486
>>
>> [-] 2 IMEI:350694801239040 used IMSI901700000002488
>>
>> [-] Total associations 2
>>
>>
>> Kind Regards,
>> Matthew
>>
>>
>>
>>
>>
>>
>> ------------------------------------------------------------------------------
>> Managing the Performance of Cloud-Based Applications
>>
>> Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
>> Read the Whitepaper.
>>
>> http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk
>> _______________________________________________
>> Openbts-discuss mailing list
>> Openbts-discuss(a)lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/openbts-discuss
>>
>>
>
>
> --
>
> Michael Mooradian
> Nathan Kunes Inc.
> 5055 North Harbor Drive, Suite 230
> San Diego, CA 92106619-822-1045 MAIN619-553-3076 DIRECT619-997-7055 CELL619-221-1235 FAXmooradianm(a)nkiengineering.com
>
>
--
Matthew Hickey
Tel: +44 7543 661237
Web: http://blog.hackerfantastic.com
Please visit my website for blog postings, status updates and project
information.
4
4
Hi all,
My first attempt to send this email didn't appear to succeed so I
am re-sending without attachment. Here is a copy of some slides
https://github.com/HackerFantastic/Public/blob/master/presentations/mwri_la…
wrote for a presentation on security weaknesses within GSM. I used an
Ettus E100 to develop a malicious BTS and GSM related attacks in a Faraday
cage and presented on how these attacks work to better understand them for
defensive purposes. I was able to use the E100 as a generic IP-router after
I cross-compiled a new kernel with netfilter enabled and also I had to
recompile a number of the packages such as Asterisk to enable ODBC and
improved SQLite support, I also had to make some changes to Python and its
modules. I used GNURadio 3.6.4 and I had to compile a specific version of
the OpenBTS code as the recent transceiver application did not function
with the E100. I was able to get the E100 to work as a GSM/GPRS router and
do real-time call placement etc. I got it to function with real-time
support and wrote a small script to provision new devices by watching the
syslog and adding to the SQLite database.
I also used osmocom-bb to do things like use gnuplot and graph the channel
usage although the code is extremely ugly! I took RSSI measurements over a
period of time into images and then tied them together for a movie, it
isn't quite realtime but it makes pretty graphs. I mentioned how you could
implement the MS side of the GSM stack using the osmocom project and as
such am sharing the slides with the osmocom list.
Just goes to show how mighty things come in small packages! Hope this
material is useful to others on the list who may also be trying similar
experiments. I ended up creating a firmware image that could be used to dd
and boot an E100 but at this time I do not plan on hosting it for download
unless there is sufficient interest. If you need it for some reason drop me
an e-mail.
Here is an example of the output of the greedyBTS script. As an example my
code plays "Rick Astley - never going to give you up" when a user places a
phone call and they have been provisioned with service. All of this work
was done in a faraday cage which I obtained from Ramsey electronics which
had very good frequency attenuation graph from 0mhz all the way to 1ghz.
root@usrp-e1xx:~# ./launch.sh
Launching asterisk
Launching HLR SMS
Launching OpenBTS
Launching Greedy BTS..
888 888 d8
e88 888 888,8, ,e e, ,e e, e88 888 Y8b Y888P 888 88e d88 dP"Y
d888 888 888 " d88 88b d88 88b d888 888 Y8b Y8P 888 888b d88888 C88b
Y888 888 888 888 , 888 , Y888 888 Y8b Y 888 888P 888 Y88D
"88 888 888 "YeeP" "YeeP" "88 888 888 888 88" 888 d,dP
, 88P 888 pDK++
"8",P" 888
[+] Current CELL configuration
[-] ==========================
[-] Shortname: 'Noone'
[-] MCC: 901 MNC: 70 C0 ARFCN: 51
[-] LAC: 3336 ARFCN's: 1 BAND: 900
[-]
[-] Radio Power
[-] ===========
[-] RxGain: 47 MaxPower: 10 MinPower: 0
--> help
[+] HELP SCREEN
[-] dump imei - lists all identified IMEI
[-] dump assoc - lists all IMEI+IMSI associations
[-] dump imsi - lists all identified IMSI
[-] dump save - store a record of all identities
[-] start service - provide service to IMSI & log traffic
[-] show service - show all provisioned phones
[-] stop service - deletes an identified IMSI from HLR
[-] calls - provide call collection statistics
[-] sms - provide sms collection statistics
[!] gprs - provide gprs collection statistics
[-] cellconfig - configure cell parameters for spoofing
[-] cellinfo - dump information on current cell
[-] cellshow - list short codes for common cells
[!] sounddial - play a sound recording to an IMSI
[!] spoofsms - send a spoof SMS message to an IMSI
[!] trunksetup - display current SIP trunk details
[-] verbose - turn on real time tracing
[-] exit - leave without shutdown
[-] shutdown - bye!
--> dump imei
[+] Dumping seen handset IMEI
[-] 1: IMEI359209002648230
[-] 2: IMEI358622002760070
[-] 3: IMEI350694801239040
[-] Total IMEI identified 3
--> dump imsi
[+] Dumping IMSI capture results
[-] 1: IMSI901700000002484
[-] 2: IMSI901700000002486
[-] 3: IMSI901700000002488
[-] Total IMSI identified 3
--> dump assoc
[+] Dumping IMSI/IMEI association
[-] 1 IMEI:358622002760070 used IMSI901700000002486
[-] 2 IMEI:350694801239040 used IMSI901700000002488
[-] Total associations 2
--> show service
[+] Displaying all provisioned IMSI
[-] 1: exten: 2100 user: IMSI001010000000000
[-] 2: exten: 2339 user: IMSI901700000002484
[-] Total subscriber count 2
--> stop service
[+] Deleting IMSI from HLR
[-] Enter IMSI: IMSI901700000002484
[-] Deleted IMSI901700000002484
--> help
[+] HELP SCREEN
[-] dump imei - lists all identified IMEI
[-] dump assoc - lists all IMEI+IMSI associations
[-] dump imsi - lists all identified IMSI
[-] dump save - store a record of all identities
[-] start service - provide service to IMSI & log traffic
[-] show service - show all provisioned phones
[-] stop service - deletes an identified IMSI from HLR
[-] calls - provide call collection statistics
[-] sms - provide sms collection statistics
[!] gprs - provide gprs collection statistics
[-] cellconfig - configure cell parameters for spoofing
[-] cellinfo - dump information on current cell
[-] cellshow - list short codes for common cells
[!] sounddial - play a sound recording to an IMSI
[!] spoofsms - send a spoof SMS message to an IMSI
[!] trunksetup - display current SIP trunk details
[-] verbose - turn on real time tracing
[-] exit - leave without shutdown
[-] shutdown - bye!
--> dump imei
[+] Dumping seen handset IMEI
[-] 1: IMEI359209002648230
[-] 2: IMEI358622002760070
[-] 3: IMEI350694801239040
[-] Total IMEI identified 3
--> dump imsi
[+] Dumping IMSI capture results
[-] 1: IMSI901700000002484
[-] 2: IMSI901700000002486
[-] 3: IMSI901700000002488
[-] Total IMSI identified 3
--> dump assoc
[+] Dumping IMSI/IMEI association
[-] 1 IMEI:358622002760070 used IMSI901700000002486
[-] 2 IMEI:350694801239040 used IMSI901700000002488
[-] Total associations 2
--> dump save
[+] Saving IMSI capture results
[+] Saving seen handset IMEI
[+] Saving IMSI/IMEI association
[-] logfile stored as 'greedybts.log'
--> shutdown
root@usrp-e1xx:~# cat greedybts.log
[-] 1: IMSI901700000002484
[-] 2: IMSI901700000002486
[-] 3: IMSI901700000002488
[-] Total IMSI identified 3
[-] 1: IMEI359209002648230
[-] 2: IMEI358622002760070
[-] 3: IMEI350694801239040
[-] Total IMEI identified 3
[-] 1 IMEI:358622002760070 used IMSI901700000002486
[-] 2 IMEI:350694801239040 used IMSI901700000002488
[-] Total associations 2
Kind Regards,
Matthew
1
0
Hi all,
Here is a copy of some slides I wrote for a presentation on
security weaknesses within GSM. I used an Ettus E100 to develop a malicious
BTS and GSM related attacks in a Faraday cage and presented on how these
attacks work to better understand them for defensive purposes. I was able
to use the E100 as a generic IP-router after I cross-compiled a new kernel
with netfilter enabled and also I had to recompile a number of the packages
such as Asterisk to enable ODBC and improved SQLite support, I also had to
make some changes to Python and its modules. I used GNURadio 3.6.4 and I
had to compile a specific version of the OpenBTS code as the recent
transceiver application did not function with the E100. I was able to get
the E100 to work as a GSM/GPRS router and do real-time call placement etc.
I got it to function with real-time support and wrote a small script to
provision new devices by watching the syslog and adding to the SQLite
database.
I also used osmocom-bb to do things like use gnuplot and graph the channel
usage although the code is extremely ugly! I took RSSI measurements over a
period of time into images and then tied them together for a movie, it
isn't quite realtime but it makes pretty graphs. I mentioned how you could
implement the MS side of the GSM stack using the osmocom project and as
such am sharing the slides here.
Just goes to show how mighty things come in small packages! Hope this
material is useful to others on the list who may also be trying similar
experiments. I ended up creating a firmware image that could be used to dd
and boot an E100 but at this time I do not plan on hosting it for download
unless there is sufficient interest. If you need it for some reason drop me
an e-mail.
Kind Regards,
Matthew
1
0
---
.gitignore | 2 +-
include/osmocom/core/bitXXgen.h.tpl | 100 ++++++++++++++++++++++++++++++++++++
include/osmocom/core/bits.h | 45 +++++++++++++++-
include/osmocom/core/msgb.h | 23 +++++----
tests/bits/bitrev_test.c | 92 ++++++++++++++++++++++++++++++++-
tests/bits/bitrev_test.ok | 22 ++++++++
6 files changed, 270 insertions(+), 14 deletions(-)
create mode 100644 include/osmocom/core/bitXXgen.h.tpl
diff --git a/.gitignore b/.gitignore
index 71b27f2..c85d04d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -89,7 +89,7 @@ doc/html.tar
src/crc*gen.c
include/osmocom/core/crc*gen.h
-
+include/osmocom/core/bit*gen.h
# vi files
*.sw?
diff --git a/include/osmocom/core/bitXXgen.h.tpl b/include/osmocom/core/bitXXgen.h.tpl
new file mode 100644
index 0000000..5714251
--- /dev/null
+++ b/include/osmocom/core/bitXXgen.h.tpl
@@ -0,0 +1,100 @@
+/*
+ * bitXXgen.h
+ *
+ * Copyright (C) 2014 Max <max.suraev(a)fairwaves.ru>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+/* Load unaligned n-byte integer (little-endian encoding) into uintXX_t */
+static inline uintXX_t osmo_loadXXle_ext(const uint8_t *p, uint8_t n)
+{
+ uint8_t i;
+ uintXX_t r = 0;
+ for(i = 0; i < n; r |= ((uintXX_t)p[i] << (8 * i)), i++);
+ return r;
+}
+
+/* Load unaligned n-byte integer (big-endian encoding) into uintXX_t */
+static inline uintXX_t osmo_loadXXbe_ext(const uint8_t *p, uint8_t n)
+{
+ uint8_t i;
+ uintXX_t r = 0;
+ for(i = 0; i < n; r |= ((uintXX_t)p[i] << (XX - 8* (1 + i))), i++);
+ return r;
+}
+
+
+/* Store unaligned n-byte integer (little-endian encoding) into uintXX_t */
+static inline void osmo_storeXXle_ext(uintXX_t x, uint8_t *p, uint8_t n)
+{
+
+
+ uint8_t i;
+ for(i = 0; i < n; p[i] = (x >> i * 8) & 0xFF, i++);
+/*
+
+ uint8_t i, adj = 8 * (8 - n);
+ uintXX_t y = (x << adj) >> adj;
+ for(i = 0; i < n; p[i] = (y >> i * 8) & 0xFF, i++);
+*/
+}
+
+/* Store unaligned n-byte integer (big-endian encoding) into uintXX_t */
+static inline void osmo_storeXXbe_ext(uintXX_t x, uint8_t *p, uint8_t n)
+{
+ uint8_t i;
+ for(i = 0; i < n; p[i] = (x >> ((n - 1 - i) * 8)) & 0xFF, i++);
+
+/*
+ uint8_t i, adj = 8 * (8 - n);
+ uintXX_t y = (x << adj) >> adj;
+ for(i = 0; i < n; p[i] = (y >> ((n - 1 - i) * 8)) & 0xFF, i++);
+*/
+}
+
+
+/* Convenience function for most-used cases */
+
+
+/* Load unaligned XX-bit integer (little-endian encoding) */
+static inline uintXX_t osmo_loadXXle(const uint8_t *p)
+{
+ return osmo_loadXXle_ext(p, XX / 8);
+}
+
+/* Load unaligned XX-bit integer (big-endian encoding) */
+static inline uintXX_t osmo_loadXXbe(const uint8_t *p)
+{
+ return osmo_loadXXbe_ext(p, XX / 8);
+}
+
+
+/* Store unaligned XX-bit integer (little-endian encoding) */
+static inline void osmo_storeXXle(uintXX_t x, uint8_t *p)
+{
+ return osmo_storeXXle_ext(x, p, XX / 8);
+}
+
+/* Store unaligned XX-bit integer (big-endian encoding) */
+static inline void osmo_storeXXbe(uintXX_t x, uint8_t *p)
+{
+ return osmo_storeXXbe_ext(x, p, XX / 8);
+}
+
+
diff --git a/include/osmocom/core/bits.h b/include/osmocom/core/bits.h
index 4c68532..c636d71 100644
--- a/include/osmocom/core/bits.h
+++ b/include/osmocom/core/bits.h
@@ -2,7 +2,9 @@
#define _OSMO_BITS_H
#include <stdint.h>
-
+#include <stddef.h>
+#include <osmocom/core/bit32gen.h>
+#include <osmocom/core/bit64gen.h>
/*! \defgroup bits soft, unpacked and packed bits
* @{
*/
@@ -15,6 +17,37 @@ typedef int8_t sbit_t; /*!< \brief soft bit (-127...127) */
typedef uint8_t ubit_t; /*!< \brief unpacked bit (0 or 1) */
typedef uint8_t pbit_t; /*!< \brief packed bis (8 bits in a byte) */
+/* Load unaligned 16-bit integer (little-endian encoding) */
+static inline uint16_t osmo_load16le(const uint8_t *p)
+{
+ return p[0] | (p[1] << 8);
+}
+
+/* Load unaligned 16-bit integer (big-endian encoding) */
+static inline uint16_t osmo_load16be(const uint8_t *p)
+{
+ return (p[0] << 8) | p[1];
+}
+
+/* Store unaligned 16-bit integer (little-endian encoding) */
+static inline void osmo_store16le(uint16_t a, uint8_t *p)
+{
+ p[0] = a & 0xFF;
+ p[1] = (a >> 8) & 0xFF;
+}
+
+/* Store unaligned 16-bit integer (big-endian encoding) */
+static inline void osmo_store16be(uint16_t a, uint8_t *p)
+{
+ p[0] = (a >> 8) & 0xFF;
+ p[1] = a & 0xFF;
+}
+
+/*
+ Less trivial LE/BE functions are autogenerated
+ see included bitXXgen.h files
+*/
+
/*
NOTE on the endianess of pbit_t:
Bits in a pbit_t are ordered MSB first, i.e. 0x80 is the first bit.
@@ -73,6 +106,16 @@ uint32_t osmo_revbytebits_8(uint8_t x);
/* \brief reverse the bits of each byte in a given buffer */
void osmo_revbytebits_buf(uint8_t *buf, int len);
+/* \brief reverse the order of the bytes in a given buffer */
+void osmo_revbytes_buf(uint8_t *buf, size_t len);
+
+/* \brief left circular shift */
+static inline uint16_t rol16(uint16_t in, unsigned shift)
+{
+ return (in << shift) | (in >> (16 - shift));
+}
+
+
/*! @} */
#endif /* _OSMO_BITS_H */
diff --git a/include/osmocom/core/msgb.h b/include/osmocom/core/msgb.h
index fe2733b..72fdc24 100644
--- a/include/osmocom/core/msgb.h
+++ b/include/osmocom/core/msgb.h
@@ -23,6 +23,7 @@
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/bits.h>
/*! \defgroup msgb Message buffers
* @{
@@ -204,8 +205,7 @@ static inline void msgb_put_u8(struct msgb *msgb, uint8_t word)
static inline void msgb_put_u16(struct msgb *msgb, uint16_t word)
{
uint8_t *space = msgb_put(msgb, 2);
- space[0] = word >> 8 & 0xFF;
- space[1] = word & 0xFF;
+ osmo_store16be(word, space);
}
/*! \brief append a uint32 value to the end of the message
@@ -215,10 +215,7 @@ static inline void msgb_put_u16(struct msgb *msgb, uint16_t word)
static inline void msgb_put_u32(struct msgb *msgb, uint32_t word)
{
uint8_t *space = msgb_put(msgb, 4);
- space[0] = word >> 24 & 0xFF;
- space[1] = word >> 16 & 0xFF;
- space[2] = word >> 8 & 0xFF;
- space[3] = word & 0xFF;
+ osmo_store32be(word, space);
}
/*! \brief remove data from end of message
@@ -235,6 +232,7 @@ static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len)
msgb->len -= len;
return tmp;
}
+
/*! \brief remove uint8 from end of message
* \param[in] msgb message buffer
* \returns 8bit value taken from end of msgb
@@ -244,6 +242,7 @@ static inline uint8_t msgb_get_u8(struct msgb *msgb)
uint8_t *space = msgb_get(msgb, 1);
return space[0];
}
+
/*! \brief remove uint16 from end of message
* \param[in] msgb message buffer
* \returns 16bit value taken from end of msgb
@@ -251,8 +250,9 @@ static inline uint8_t msgb_get_u8(struct msgb *msgb)
static inline uint16_t msgb_get_u16(struct msgb *msgb)
{
uint8_t *space = msgb_get(msgb, 2);
- return space[0] << 8 | space[1];
+ return osmo_load16be(space);
}
+
/*! \brief remove uint32 from end of message
* \param[in] msgb message buffer
* \returns 32bit value taken from end of msgb
@@ -260,7 +260,7 @@ static inline uint16_t msgb_get_u16(struct msgb *msgb)
static inline uint32_t msgb_get_u32(struct msgb *msgb)
{
uint8_t *space = msgb_get(msgb, 4);
- return space[0] << 24 | space[1] << 16 | space[2] << 8 | space[3];
+ return osmo_load32be(space);
}
/*! \brief prepend (push) some data to start of message
@@ -284,6 +284,7 @@ static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)
msgb->len += len;
return msgb->data;
}
+
/*! \brief remove (pull) a header from the front of the message buffer
* \param[in] msgb message buffer
* \param[in] len number of octets to be pulled
@@ -308,6 +309,7 @@ static inline uint8_t msgb_pull_u8(struct msgb *msgb)
uint8_t *space = msgb_pull(msgb, 1) - 1;
return space[0];
}
+
/*! \brief remove uint16 from front of message
* \param[in] msgb message buffer
* \returns 16bit value taken from end of msgb
@@ -315,8 +317,9 @@ static inline uint8_t msgb_pull_u8(struct msgb *msgb)
static inline uint16_t msgb_pull_u16(struct msgb *msgb)
{
uint8_t *space = msgb_pull(msgb, 2) - 2;
- return space[0] << 8 | space[1];
+ return osmo_load16be(space);
}
+
/*! \brief remove uint32 from front of message
* \param[in] msgb message buffer
* \returns 32bit value taken from end of msgb
@@ -324,7 +327,7 @@ static inline uint16_t msgb_pull_u16(struct msgb *msgb)
static inline uint32_t msgb_pull_u32(struct msgb *msgb)
{
uint8_t *space = msgb_pull(msgb, 4) - 4;
- return space[0] << 24 | space[1] << 16 | space[2] << 8 | space[3];
+ return osmo_load32be(space);
}
/*! \brief Increase headroom of empty msgb, reducing the tailroom
diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c
index 5eca990..6cf340e 100644
--- a/tests/bits/bitrev_test.c
+++ b/tests/bits/bitrev_test.c
@@ -1,8 +1,9 @@
-
+#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
+#include <time.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/bits.h>
@@ -10,11 +11,66 @@
static const uint8_t input[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
static const uint8_t exp_out[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+char s[18], *p;
+
+void check_ls_64(uint8_t bytes)
+{
+ uint8_t T[bytes], D = (8 - bytes), A = 8 * D, C = 2 * D;
+ uint64_t _test = ((uint64_t)rand() << 32) + rand(), a_test = (_test << A) >> A;
+
+ osmo_store64be_ext(_test, T, bytes);
+ snprintf(s, 17, "%.16" PRIx64, a_test);
+ p = osmo_hexdump_nospc(T, bytes);
+ if (0 != memcmp(s + C, p, bytes)) {
+ printf("%s\t%s\t%u BE store FAILED!\n", s + C, p, bytes * 8);
+ } else printf("%u BE store OK\n", bytes * 8);
+
+ osmo_store64le_ext(_test, T, bytes);
+ if (osmo_load64le_ext(T, bytes) == a_test)
+ printf("%u LE OK\n", bytes * 8);
+ else
+ printf("%u LE FAILED on %s- loaded %.16" PRIx64 " instead of %.16" PRIx64 "\n", bytes * 8, osmo_hexdump(T, bytes), osmo_load64le_ext(T, bytes), a_test);
+
+ osmo_store64be_ext(_test, T, bytes);
+ if (osmo_load64be_ext(T, bytes) == (a_test << A))
+ printf("%u BE OK\n", bytes * 8);
+ else
+ printf("%u BE FAILED on %s- loaded %.16" PRIx64 " instead of %.16" PRIx64 "\n", bytes * 8, osmo_hexdump(T, bytes), osmo_load64be_ext(T, bytes), (a_test << A));
+}
+
+void check_ls_32(uint8_t bytes)
+{
+ uint8_t T[bytes], D = (4 - bytes), A = 8 * D, C = 2 * D;
+ uint32_t _test = rand(), a_test = (_test << A) >> A;
+
+ osmo_store32be_ext(_test, T, bytes);
+ snprintf(s, 17, "%.8" PRIx32, a_test);
+ p = osmo_hexdump_nospc(T, bytes);
+ if (0 != memcmp(s + C, p, bytes)) {
+ printf("%s\t%s\t%u BE store FAILED on %" PRIx32 "\n", s + C, p, bytes * 8, _test);
+ } else printf("%u BE store OK\n", bytes * 8);
+
+ osmo_store32le_ext(_test, T, bytes);
+ if (osmo_load32le_ext(T, bytes) == a_test)
+ printf("%u LE OK\n", bytes * 8);
+ else
+ printf("%u LE FAILED on %s- loaded %.8" PRIx32 " instead of %.8" PRIx32 "\n", bytes * 8, osmo_hexdump(T, bytes), osmo_load32le_ext(T, bytes), a_test);
+
+ osmo_store32be_ext(_test, T, bytes);
+ if (osmo_load32be_ext(T, bytes) == (a_test << A))
+ printf("%u BE OK\n", bytes * 8);
+ else
+ printf("%u BE FAILED on %s- loaded %.8" PRIx32 " instead of %.8" PRIx32 "\n", bytes * 8, osmo_hexdump(T, bytes), osmo_load32be_ext(T, bytes), (a_test << A));
+}
+
int main(int argc, char **argv)
{
- uint8_t out[ARRAY_SIZE(input)];
+ uint8_t out[ARRAY_SIZE(input)], test[8];
unsigned int offs;
+
+ srand(time(NULL));
+
for (offs = 0; offs < sizeof(out); offs++) {
uint8_t *start = out + offs;
uint8_t len = sizeof(out) - offs;
@@ -32,5 +88,37 @@ int main(int argc, char **argv)
printf("\n");
}
+ printf("checking byte packing...\n");
+
+ check_ls_64(8);
+ check_ls_64(7);
+ check_ls_64(6);
+ check_ls_64(5);
+ check_ls_32(4);
+ check_ls_32(3);
+
+ uint16_t _test16 = (uint16_t)rand();
+ osmo_store16be(_test16, test);
+
+ snprintf(s, 17, "%.4" PRIx16, _test16);
+ p = osmo_hexdump_nospc(test, 2);
+ if (0 != memcmp(s, p, 2)) {
+ printf ("%s\t", s);
+ printf ("%s\t", p);
+ printf("16 BE FAILED on %" PRIx16 "\n");
+ } else printf("16 BE store OK\n");
+
+ osmo_store16le(_test16, test);
+ if (osmo_load16le(test) == _test16)
+ printf("16 LE OK\n");
+ else
+ printf("16 LE FAILED: %s, %.4" PRIx16 ", %.4" PRIx16 "\n", osmo_hexdump(test, 2), osmo_load16le(test), _test16);
+
+ osmo_store16be(_test16, test);
+ if (osmo_load16be(test) == _test16)
+ printf("16 BE OK\n");
+ else
+ printf("16 BE FAILED: %s, %.4" PRIx16 ", %.4" PRIx16 "\n", osmo_hexdump(test, 2), osmo_load16be(test), _test16);
+
return 0;
}
diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok
index 47f402f..0cbc4db 100644
--- a/tests/bits/bitrev_test.ok
+++ b/tests/bits/bitrev_test.ok
@@ -22,3 +22,25 @@ REVERSED: 02 01
INORDER: 80
REVERSED: 01
+checking byte packing...
+64 BE store OK
+64 LE OK
+64 BE OK
+56 BE store OK
+56 LE OK
+56 BE OK
+48 BE store OK
+48 LE OK
+48 BE OK
+40 BE store OK
+40 LE OK
+40 BE OK
+32 BE store OK
+32 LE OK
+32 BE OK
+24 BE store OK
+24 LE OK
+24 BE OK
+16 BE store OK
+16 LE OK
+16 BE OK
--
1.8.3.2
--------------060004070705090302070204
Content-Type: text/x-patch;
name="0002-Add-Kasumi-cipher-implementation.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="0002-Add-Kasumi-cipher-implementation.patch"
1
0
---
.gitignore | 2 +
include/Makefile.am | 6 ++
include/osmocom/gsm/kasumi.h | 36 ++++++++
src/gsm/Makefile.am | 2 +-
src/gsm/kasumi.c | 193 +++++++++++++++++++++++++++++++++++++++++++
src/gsm/libosmogsm.map | 4 +
tests/Makefile.am | 7 +-
tests/kasumi/kasumi_test.c | 128 ++++++++++++++++++++++++++++
tests/kasumi/kasumi_test.ok | 10 +++
tests/testsuite.at | 6 ++
10 files changed, 391 insertions(+), 3 deletions(-)
create mode 100644 include/osmocom/gsm/kasumi.h
create mode 100644 src/gsm/kasumi.c
create mode 100644 tests/kasumi/kasumi_test.c
create mode 100644 tests/kasumi/kasumi_test.ok
diff --git a/.gitignore b/.gitignore
index c85d04d..1299028 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,8 @@ tests/testsuite
tests/testsuite.dir/
tests/testsuite.log
+tests/utils/utils_test
+tests/kasumi/kasumi_test
tests/sms/sms_test
tests/timer/timer_test
tests/msgfile/msgfile_test
diff --git a/include/Makefile.am b/include/Makefile.am
index b035906..18011ff 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -2,6 +2,8 @@ nobase_include_HEADERS = \
osmocom/codec/codec.h \
osmocom/core/application.h \
osmocom/core/backtrace.h \
+ osmocom/core/bit32gen.h \
+ osmocom/core/bit64gen.h \
osmocom/core/bits.h \
osmocom/core/bitvec.h \
osmocom/core/conv.h \
@@ -107,6 +109,10 @@ endif
noinst_HEADERS = osmocom/core/timer_compat.h
+osmocom/core/bit%gen.h: osmocom/core/bitXXgen.h.tpl
+ $(AM_V_GEN)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)sed -e's/XX/$*/g' $< > $@
+
osmocom/core/crc%gen.h: osmocom/core/crcXXgen.h.tpl
$(AM_V_GEN)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)sed -e's/XX/$*/g' $< > $@
diff --git a/include/osmocom/gsm/kasumi.h b/include/osmocom/gsm/kasumi.h
new file mode 100644
index 0000000..8479968
--- /dev/null
+++ b/include/osmocom/gsm/kasumi.h
@@ -0,0 +1,36 @@
+/*
+ * KASUMI header
+ *
+ * See kasumi.c for details
+ */
+
+#ifndef __KASUMI_H__
+#define __KASUMI_H__
+
+#include <stdint.h>
+
+/*
+ * Single iteration of KASUMI cipher
+*/
+uint64_t _kasumi(uint64_t P, uint16_t *KLi1, uint16_t *KLi2, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3);
+
+/*
+ * Implementation of the KGCORE algorithm (used by A5/3, A5/4, GEA3, GEA4 and ECSD)
+ *
+ * CA : uint8_t
+ * cb : uint8_t
+ * cc : uint32_t
+ * cd : uint8_t
+ * ck : uint8_t [8]
+ * co : uint8_t [output, cl-dependent]
+ * cl : uint16_t
+ */
+void _kasumi_kgcore(uint8_t CA, uint8_t cb, uint32_t cc, uint8_t cd, const uint8_t *ck, uint8_t *co, uint16_t cl);
+
+/*! \brief Expand key into set of subkeys
+ * \param[in] key (128 bits) as array of bytes
+ * \param[out] arrays of round-specific subkeys - see TS 135 202 for details
+ */
+void _kasumi_key_expand(const uint8_t *key, uint16_t *KLi1, uint16_t *KLi2, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3);
+
+#endif /* __KASUMI_H__ */
diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am
index 3162a7f..8ccbaec 100644
--- a/src/gsm/Makefile.am
+++ b/src/gsm/Makefile.am
@@ -15,7 +15,7 @@ libosmogsm_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c comp128v23.c \
gsm_utils.c rsl.c gsm48.c gsm48_ie.c gsm0808.c sysinfo.c \
gprs_cipher_core.c gsm0480.c abis_nm.c gsm0502.c \
gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \
- lapd_core.c lapdm.c \
+ lapd_core.c lapdm.c kasumi.c \
auth_core.c auth_comp128v1.c auth_comp128v23.c \
auth_milenage.c milenage/aes-encblock.c \
milenage/aes-internal.c milenage/aes-internal-enc.c \
diff --git a/src/gsm/kasumi.c b/src/gsm/kasumi.c
new file mode 100644
index 0000000..9900e05
--- /dev/null
+++ b/src/gsm/kasumi.c
@@ -0,0 +1,193 @@
+/* Kasumi cipher and KGcore functions */
+
+/* (C) 2013 by Max <Max.Suraev(a)fairwaves.ru>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+#include <osmocom/gsm/kasumi.h>
+
+static uint16_t
+_kasumi_FI(uint16_t I, uint16_t skey)
+{
+ static uint16_t S7[] = {
+ 54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18, 123, 33,
+ 55, 113, 39, 114, 21, 67, 65, 12, 47, 73, 46, 27, 25, 111, 124, 81,
+ 53, 9, 121, 79, 52, 60, 58, 48, 101, 127, 40, 120, 104, 70, 71, 43,
+ 20, 122, 72, 61, 23, 109, 13, 100, 77, 1, 16, 7, 82, 10, 105, 98,
+ 117, 116, 76, 11, 89, 106, 0,125,118, 99, 86, 69, 30, 57, 126, 87,
+ 112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66,
+ 102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29, 115, 44,
+ 64, 107, 108, 24, 110, 83, 36, 78, 42, 19, 15, 41, 88, 119, 59, 3
+ };
+ static uint16_t S9[] = {
+ 167, 239, 161, 379, 391, 334, 9, 338, 38, 226, 48, 358, 452, 385, 90, 397,
+ 183, 253, 147, 331, 415, 340, 51, 362, 306, 500, 262, 82, 216, 159, 356, 177,
+ 175, 241, 489, 37, 206, 17, 0, 333, 44, 254, 378, 58, 143, 220, 81, 400,
+ 95, 3, 315, 245, 54, 235, 218, 405, 472, 264, 172, 494, 371, 290, 399, 76,
+ 165, 197, 395, 121, 257, 480, 423, 212, 240, 28, 462, 176, 406, 507, 288, 223,
+ 501, 407, 249, 265, 89, 186, 221, 428,164, 74, 440, 196, 458, 421, 350, 163,
+ 232, 158, 134, 354, 13, 250, 491, 142,191, 69, 193, 425, 152, 227, 366, 135,
+ 344, 300, 276, 242, 437, 320, 113, 278, 11, 243, 87, 317, 36, 93, 496, 27,
+ 487, 446, 482, 41, 68, 156, 457, 131, 326, 403, 339, 20, 39, 115, 442, 124,
+ 475, 384, 508, 53, 112, 170, 479, 151, 126, 169, 73, 268, 279, 321, 168, 364,
+ 363, 292, 46, 499, 393, 327, 324, 24, 456, 267, 157, 460, 488, 426, 309, 229,
+ 439, 506, 208, 271, 349, 401, 434, 236, 16, 209, 359, 52, 56, 120, 199, 277,
+ 465, 416, 252, 287, 246, 6, 83, 305, 420, 345, 153,502, 65, 61, 244, 282,
+ 173, 222, 418, 67, 386, 368, 261, 101, 476, 291, 195,430, 49, 79, 166, 330,
+ 280, 383, 373, 128, 382, 408, 155, 495, 367, 388, 274, 107, 459, 417, 62, 454,
+ 132, 225, 203, 316, 234, 14, 301, 91, 503, 286, 424, 211, 347, 307, 140, 374,
+ 35, 103, 125, 427, 19, 214, 453, 146, 498, 314, 444, 230, 256, 329, 198, 285,
+ 50, 116, 78, 410, 10, 205, 510, 171, 231, 45, 139, 467, 29, 86, 505, 32,
+ 72, 26, 342, 150, 313, 490, 431, 238, 411, 325, 149, 473, 40, 119, 174, 355,
+ 185, 233, 389, 71, 448, 273, 372, 55, 110, 178, 322, 12, 469, 392, 369, 190,
+ 1, 109, 375, 137, 181, 88, 75, 308, 260, 484, 98, 272, 370, 275, 412, 111,
+ 336, 318, 4, 504, 492, 259, 304, 77, 337, 435, 21, 357, 303, 332, 483, 18,
+ 47, 85, 25, 497, 474, 289, 100, 269, 296, 478, 270, 106, 31, 104, 433, 84,
+ 414, 486, 394, 96, 99, 154, 511, 148, 413, 361, 409, 255, 162, 215, 302, 201,
+ 266, 351, 343, 144, 441, 365, 108, 298, 251, 34, 182, 509, 138, 210, 335, 133,
+ 311, 352, 328, 141, 396, 346, 123, 319, 450, 281, 429, 228, 443, 481, 92, 404,
+ 485, 422, 248, 297, 23, 213, 130, 466, 22, 217, 283, 70, 294, 360, 419, 127,
+ 312, 377, 7, 468, 194, 2, 117, 295, 463, 258, 224, 447, 247, 187, 80, 398,
+ 284, 353, 105, 390, 299, 471, 470, 184, 57, 200, 348, 63, 204, 188, 33, 451,
+ 97, 30, 310, 219, 94, 160, 129, 493, 64, 179, 263, 102, 189, 207, 114, 402,
+ 438, 477, 387, 122, 192, 42, 381, 5, 145, 118, 180, 449, 293, 323, 136, 380,
+ 43, 66, 60, 455, 341, 445, 202, 432, 8, 237, 15, 376, 436, 464, 59, 461
+ };
+ uint16_t L, R;
+
+ /* Split 16 bit input into two unequal halves: 9 and 7 bits, same for subkey */
+ L = I >> 7; /* take 9 bits */
+ R = I & 0x7F; /* take 7 bits */
+
+ L = S9[L] ^ R;
+ R = S7[R] ^ (L & 0x7F);
+
+ L ^= (skey & 0x1FF);
+ R ^= (skey >> 9);
+
+ L = S9[L] ^ R;
+ R = S7[R] ^ (L & 0x7F);
+
+ return (R << 9) + L;
+}
+
+static uint32_t
+_kasumi_FO(uint32_t I, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3, unsigned i)
+{
+ uint16_t L = I >> 16, R = I; /* Split 32 bit input into Left and Right parts */
+
+ L ^= KOi1[i];
+ L = _kasumi_FI(L, KIi1[i]);
+ L ^= R;
+
+ R ^= KOi2[i];
+ R = _kasumi_FI(R, KIi2[i]);
+ R ^= L;
+
+ L ^= KOi3[i];
+ L = _kasumi_FI(L, KIi3[i]);
+ L ^= R;
+
+ return (((uint32_t)R) << 16) + L;
+}
+
+static uint32_t
+_kasumi_FL(uint32_t I, uint16_t *KLi1, uint16_t *KLi2, unsigned i)
+{
+ uint16_t L = I >> 16, R = I, tmp; /* Split 32 bit input into Left and Right parts */
+
+ tmp = L & KLi1[i];
+ R ^= rol16(tmp, 1);
+
+ tmp = R | KLi2[i];
+ L ^= rol16(tmp, 1);
+
+ return (((uint32_t)L) << 16) + R;
+}
+
+uint64_t
+_kasumi(uint64_t P, uint16_t *KLi1, uint16_t *KLi2, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3)
+{
+ uint32_t i, L = P >> 32, R = P; /* Split 64 bit input into Left and Right parts */
+
+ for (i = 0; i < 8; i++)
+ {
+ R ^= _kasumi_FO(_kasumi_FL(L, KLi1, KLi2, i), KOi1, KOi2, KOi3, KIi1, KIi2, KIi3, i); /* odd round */
+ i++;
+ L ^= _kasumi_FL(_kasumi_FO(R, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3, i), KLi1, KLi2, i); /* even round */
+ }
+ return (((uint64_t)L) << 32) + R; /* Concatenate Left and Right 32 bits into 64 bit ciphertext */
+}
+
+/*! \brief Expand key into set of subkeys
+ * \param[in] key (128 bits) as array of bytes
+ * \param[out] arrays of round-specific subkeys - see TS 135 202 for details
+ */
+void
+_kasumi_key_expand(const uint8_t *key, uint16_t *KLi1, uint16_t *KLi2, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3)
+{
+ uint16_t i, C[] = { 0x0123, 0x4567, 0x89AB, 0xCDEF, 0xFEDC, 0xBA98, 0x7654, 0x3210 };
+
+ for (i = 0; i < 8; i++) /* Work with 16 bit subkeys and create prime subkeys */
+ {
+ C[i] ^= osmo_load16be(key + i * 2);
+ }
+ /* C[] now stores K-prime[] */
+ for (i = 0; i < 8; i++) /* Create round-specific subkeys */
+ {
+ KLi1[i] = rol16(osmo_load16be(key + i * 2), 1);
+ KLi2[i] = C[(i + 2) & 0x7];
+
+ KOi1[i] = rol16(osmo_load16be(key + ((2 * (i + 1)) & 0xE)), 5);
+ KOi2[i] = rol16(osmo_load16be(key + ((2 * (i + 5)) & 0xE)), 8);
+ KOi3[i] = rol16(osmo_load16be(key + ((2 * (i + 6)) & 0xE)), 13);
+
+ KIi1[i] = C[(i + 4) & 0x7];
+ KIi2[i] = C[(i + 3) & 0x7];
+ KIi3[i] = C[(i + 7) & 0x7];
+ }
+}
+
+void
+_kasumi_kgcore(uint8_t CA, uint8_t cb, uint32_t cc, uint8_t cd, const uint8_t *ck, uint8_t *co, uint16_t cl)
+{
+ uint16_t KLi1[8], KLi2[8], KOi1[8], KOi2[8], KOi3[8], KIi1[8], KIi2[8], KIi3[8], i;
+ uint64_t A = ((uint64_t)cc) << 32, BLK = 0, _ca = ((uint64_t)CA << 16) ;
+ A |= _ca;
+ _ca = (uint64_t)((cb << 3) | (cd << 2)) << 24;
+ A |= _ca;
+ /* Register loading complete: see TR 55.919 8.2 and TS 55.216 3.2 */
+
+ uint8_t ck_km[16];
+ for (i = 0; i < 16; i++) ck_km[i] = ck[i] ^ 0x55; /* Modified key established */
+
+ /* preliminary round with modified key */
+ _kasumi_key_expand(ck_km, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
+ A = _kasumi(A, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
+
+ /* Run Kasumi in OFB to obtain enough data for gamma. */
+ _kasumi_key_expand(ck, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
+ for (i = 0; i < cl / 64 + 1; i++) /* i is a block counter */
+ {
+ BLK = _kasumi(A ^ i ^ BLK, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
+ osmo_store64be(BLK, co + (i * 8));
+ }
+}
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 9d15d66..3a4a643 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -196,6 +196,10 @@ osmo_a5;
osmo_a5_1;
osmo_a5_2;
+_kasumi;
+_kasumi_key_expand;
+_kasumi_kgcore;
+
osmo_auth_alg_name;
osmo_auth_alg_parse;
osmo_auth_gen_vec;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c6216d5..ddc13dc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,7 +4,7 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \
smscb/smscb_test bits/bitrev_test a5/a5_test \
conv/conv_test auth/milenage_test lapd/lapd_test \
gsm0808/gsm0808_test gsm0408/gsm0408_test \
- gb/bssgp_fc_test gb/gprs_ns_test \
+ gb/bssgp_fc_test gb/gprs_ns_test kasumi/kasumi_test \
logging/logging_test fr/fr_test \
loggingrb/loggingrb_test strrb/strrb_test \
vty/vty_test comp128/comp128_test utils/utils_test
@@ -19,6 +19,9 @@ utils_utils_test_LDADD = $(top_builddir)/src/libosmocore.la
a5_a5_test_SOURCES = a5/a5_test.c
a5_a5_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
+kasumi_kasumi_test_SOURCES = kasumi/kasumi_test.c
+kasumi_kasumi_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
+
comp128_comp128_test_SOURCES = comp128/comp128_test.c
comp128_comp128_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
@@ -102,7 +105,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
lapd/lapd_test.ok gsm0408/gsm0408_test.ok \
gsm0808/gsm0808_test.ok gb/bssgp_fc_tests.err \
gb/bssgp_fc_tests.ok gb/bssgp_fc_tests.sh \
- gb/gprs_ns_test.ok \
+ gb/gprs_ns_test.ok kasumi/kasumi_test.ok \
msgfile/msgfile_test.ok msgfile/msgconfig.cfg \
logging/logging_test.ok logging/logging_test.err \
fr/fr_test.ok loggingrb/logging_test.ok \
diff --git a/tests/kasumi/kasumi_test.c b/tests/kasumi/kasumi_test.c
new file mode 100644
index 0000000..fbe23a9
--- /dev/null
+++ b/tests/kasumi/kasumi_test.c
@@ -0,0 +1,128 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/gsm/kasumi.h>
+
+
+inline int _compare_mem(uint8_t * x, uint8_t * y, size_t len) {
+ if (0 != memcmp(x, y, len)) {
+ printf ("X: %s\t", osmo_hexdump_nospc(x, len));
+ printf ("Y: %s\n", osmo_hexdump_nospc(y, len));
+ return 0;
+ }
+ return 1;
+}
+
+inline static void test_expansion(uint8_t * test_key, uint16_t * _KLi1, uint16_t * _KLi2, uint16_t * _KOi1, uint16_t * _KOi2, uint16_t * _KOi3, uint16_t * _KIi1, uint16_t * _KIi2, uint16_t * _KIi3, uint16_t * _KLi1_r, uint16_t * _KLi2_r, uint16_t * _KOi1_r, uint16_t * _KOi2_r, uint16_t * _KOi3_r, uint16_t * _KIi1_r, uint16_t * _KIi2_r, uint16_t * _KIi3_r)
+{
+ _kasumi_key_expand(test_key, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3);
+ int passed = 1;
+ passed = _compare_mem((uint8_t *)_KLi1, (uint8_t *)_KLi1_r, 16);
+ passed = _compare_mem((uint8_t *)_KLi2, (uint8_t *)_KLi2_r, 16);
+ passed = _compare_mem((uint8_t *)_KOi1, (uint8_t *)_KOi1_r, 16);
+ passed = _compare_mem((uint8_t *)_KOi2, (uint8_t *)_KOi2_r, 16);
+ passed = _compare_mem((uint8_t *)_KOi3, (uint8_t *)_KOi3_r, 16);
+ passed = _compare_mem((uint8_t *)_KIi1, (uint8_t *)_KIi1_r, 16);
+ passed = _compare_mem((uint8_t *)_KIi2, (uint8_t *)_KIi2_r, 16);
+ passed = _compare_mem((uint8_t *)_KIi3, (uint8_t *)_KIi3_r, 16);
+ if (passed) printf(" OK. "); else printf("FAILED!");
+}
+
+int main(int argc, char **argv)
+{
+ uint16_t _KLi1[8], _KLi2[8], _KOi1[8], _KOi2[8], _KOi3[8], _KIi1[8], _KIi2[8], _KIi3[8], _KLi1_r[8], _KLi2_r[8], _KOi1_r[8], _KOi2_r[8], _KOi3_r[8], _KIi1_r[8], _KIi2_r[8], _KIi3_r[8];
+
+ printf("testing KASUMI key expansion and encryption (ETSI TS 135 203):\n");
+ printf("KASUMI Test Set 1...");
+
+uint8_t _test_key1[] = {0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00, 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48};
+_KLi1_r[0] = 0x57AC; _KLi1_r[1] = 0x8B3E; _KLi1_r[2] = 0x058B; _KLi1_r[3] = 0x6601; _KLi1_r[4] = 0x2A59; _KLi1_r[5] = 0x9220; _KLi1_r[6] = 0x9102; _KLi1_r[7] = 0xFE91;
+_KLi2_r[0] = 0x0B6E; _KLi2_r[1] = 0x7EEF; _KLi2_r[2] = 0x6BF0; _KLi2_r[3] = 0xF388; _KLi2_r[4] = 0x3ED5; _KLi2_r[5] = 0xCD58; _KLi2_r[6] = 0x2AF5; _KLi2_r[7] = 0x00F8;
+_KOi1_r[0] = 0xB3E8; _KOi1_r[1] = 0x58B0; _KOi1_r[2] = 0x6016; _KOi1_r[3] = 0xA592; _KOi1_r[4] = 0x2209; _KOi1_r[5] = 0x1029; _KOi1_r[6] = 0xE91F; _KOi1_r[7] = 0x7AC5;
+_KOi2_r[0] = 0x1049; _KOi2_r[1] = 0x8148; _KOi2_r[2] = 0x48FF; _KOi2_r[3] = 0xD62B; _KOi2_r[4] = 0x9F45; _KOi2_r[5] = 0xC582; _KOi2_r[6] = 0x00B3; _KOi2_r[7] = 0x2C95;
+_KOi3_r[0] = 0x2910; _KOi3_r[1] = 0x1FE9; _KOi3_r[2] = 0xC57A; _KOi3_r[3] = 0xE8B3; _KOi3_r[4] = 0xB058; _KOi3_r[5] = 0x1660; _KOi3_r[6] = 0x92A5; _KOi3_r[7] = 0x0922;
+_KIi1_r[0] = 0x6BF0; _KIi1_r[1] = 0xF388; _KIi1_r[2] = 0x3ED5; _KIi1_r[3] = 0xCD58; _KIi1_r[4] = 0x2AF5; _KIi1_r[5] = 0x00F8; _KIi1_r[6] = 0x0B6E; _KIi1_r[7] = 0x7EEF;
+_KIi2_r[0] = 0x7EEF; _KIi2_r[1] = 0x6BF0; _KIi2_r[2] = 0xF388; _KIi2_r[3] = 0x3ED5; _KIi2_r[4] = 0xCD58; _KIi2_r[5] = 0x2AF5; _KIi2_r[6] = 0x00F8; _KIi2_r[7] = 0x0B6E;
+_KIi3_r[0] = 0xCD58; _KIi3_r[1] = 0x2AF5; _KIi3_r[2] = 0x00F8; _KIi3_r[3] = 0x0B6E; _KIi3_r[4] = 0x7EEF; _KIi3_r[5] = 0x6BF0; _KIi3_r[6] = 0xF388; _KIi3_r[7] = 0x3ED5;
+test_expansion(_test_key1, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3, _KLi1_r, _KLi2_r, _KOi1_r, _KOi2_r, _KOi3_r, _KIi1_r, _KIi2_r, _KIi3_r);
+
+if (0xDF1F9B251C0BF45F == _kasumi(0xEA024714AD5C4D84, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3))
+ printf("OK."); else printf("FAILED!");
+
+printf("\nKASUMI Test Set 2...");
+
+uint8_t _test_key2[] = {0x8C, 0xE3, 0x3E, 0x2C, 0xC3, 0xC0, 0xB5, 0xFC, 0x1F, 0x3D, 0xE8, 0xA6, 0xDC, 0x66, 0xB1, 0xF3};
+_KLi1_r[0] = 0x19C7; _KLi1_r[1] = 0x7C58; _KLi1_r[2] = 0x8781; _KLi1_r[3] = 0x6BF9; _KLi1_r[4] = 0x3E7A; _KLi1_r[5] = 0xD14D; _KLi1_r[6] = 0xB8CD; _KLi1_r[7] = 0x63E7;
+_KLi2_r[0] = 0x4A6B; _KLi2_r[1] = 0x7813; _KLi2_r[2] = 0xE1E1; _KLi2_r[3] = 0x523E; _KLi2_r[4] = 0xAA32; _KLi2_r[5] = 0x83E3; _KLi2_r[6] = 0x8DC0; _KLi2_r[7] = 0x7B4B;
+_KOi1_r[0] = 0xC587; _KOi1_r[1] = 0x7818; _KOi1_r[2] = 0xBF96; _KOi1_r[3] = 0xE7A3; _KOi1_r[4] = 0x14DD; _KOi1_r[5] = 0x8CDB; _KOi1_r[6] = 0x3E76; _KOi1_r[7] = 0x9C71;
+_KOi2_r[0] = 0xA6E8; _KOi2_r[1] = 0x66DC; _KOi2_r[2] = 0xF3B1; _KOi2_r[3] = 0xE38C; _KOi2_r[4] = 0x2C3E; _KOi2_r[5] = 0xC0C3; _KOi2_r[6] = 0xFCB5; _KOi2_r[7] = 0x3D1F;
+_KOi3_r[0] = 0xDB8C; _KOi3_r[1] = 0x763E; _KOi3_r[2] = 0x719C; _KOi3_r[3] = 0x87C5; _KOi3_r[4] = 0x1878; _KOi3_r[5] = 0x96BF; _KOi3_r[6] = 0xA3E7; _KOi3_r[7] = 0xDD14;
+_KIi1_r[0] = 0xE1E1; _KIi1_r[1] = 0x523E; _KIi1_r[2] = 0xAA32; _KIi1_r[3] = 0x83E3; _KIi1_r[4] = 0x8DC0; _KIi1_r[5] = 0x7B4B; _KIi1_r[6] = 0x4A6B; _KIi1_r[7] = 0x7813;
+_KIi2_r[0] = 0x7813; _KIi2_r[1] = 0xE1E1; _KIi2_r[2] = 0x523E; _KIi2_r[3] = 0xAA32; _KIi2_r[4] = 0x83E3; _KIi2_r[5] = 0x8DC0; _KIi2_r[6] = 0x7B4B; _KIi2_r[7] = 0x4A6B;
+_KIi3_r[0] = 0x83E3; _KIi3_r[1] = 0x8DC0; _KIi3_r[2] = 0x7B4B; _KIi3_r[3] = 0x4A6B; _KIi3_r[4] = 0x7813; _KIi3_r[5] = 0xE1E1; _KIi3_r[6] = 0x523E; _KIi3_r[7] = 0xAA32;
+test_expansion(_test_key2, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3, _KLi1_r, _KLi2_r, _KOi1_r, _KOi2_r, _KOi3_r, _KIi1_r, _KIi2_r, _KIi3_r);
+
+if (0xDE551988CEB2F9B7 == _kasumi(0xD3C5D592327FB11C, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3))
+ printf("OK."); else printf("FAILED!");
+
+printf("\nKASUMI Test Set 3...");
+
+uint8_t _test_key3[] = {0x40, 0x35, 0xC6, 0x68, 0x0A, 0xF8, 0xC6, 0xD1, 0xA8, 0xFF, 0x86, 0x67, 0xB1, 0x71, 0x40, 0x13};
+_KLi1_r[0] = 0x806A; _KLi1_r[1] = 0x8CD1; _KLi1_r[2] = 0x15F0; _KLi1_r[3] = 0x8DA3; _KLi1_r[4] = 0x51FF; _KLi1_r[5] = 0x0CCF; _KLi1_r[6] = 0x62E3; _KLi1_r[7] = 0x8026;
+_KLi2_r[0] = 0x8353; _KLi2_r[1] = 0x0B3E; _KLi2_r[2] = 0x5623; _KLi2_r[3] = 0x3CFF; _KLi2_r[4] = 0xC725; _KLi2_r[5] = 0x7203; _KLi2_r[6] = 0x4116; _KLi2_r[7] = 0x830F;
+_KOi1_r[0] = 0xCD18; _KOi1_r[1] = 0x5F01; _KOi1_r[2] = 0xDA38; _KOi1_r[3] = 0x1FF5; _KOi1_r[4] = 0xCCF0; _KOi1_r[5] = 0x2E36; _KOi1_r[6] = 0x0268; _KOi1_r[7] = 0x06A8;
+_KOi2_r[0] = 0x6786; _KOi2_r[1] = 0x71B1; _KOi2_r[2] = 0x1340; _KOi2_r[3] = 0x3540; _KOi2_r[4] = 0x68C6; _KOi2_r[5] = 0xF80A; _KOi2_r[6] = 0xD1C6; _KOi2_r[7] = 0xFFA8;
+_KOi3_r[0] = 0x362E; _KOi3_r[1] = 0x6802; _KOi3_r[2] = 0xA806; _KOi3_r[3] = 0x18CD; _KOi3_r[4] = 0x015F; _KOi3_r[5] = 0x38DA; _KOi3_r[6] = 0xF51F; _KOi3_r[7] = 0xF0CC;
+_KIi1_r[0] = 0x5623; _KIi1_r[1] = 0x3CFF; _KIi1_r[2] = 0xC725; _KIi1_r[3] = 0x7203; _KIi1_r[4] = 0x4116; _KIi1_r[5] = 0x830F; _KIi1_r[6] = 0x8353; _KIi1_r[7] = 0x0B3E;
+_KIi2_r[0] = 0x0B3E; _KIi2_r[1] = 0x5623; _KIi2_r[2] = 0x3CFF; _KIi2_r[3] = 0xC725; _KIi2_r[4] = 0x7203; _KIi2_r[5] = 0x4116; _KIi2_r[6] = 0x830F; _KIi2_r[7] = 0x8353;
+_KIi3_r[0] = 0x7203; _KIi3_r[1] = 0x4116; _KIi3_r[2] = 0x830F; _KIi3_r[3] = 0x8353; _KIi3_r[4] = 0x0B3E; _KIi3_r[5] = 0x5623; _KIi3_r[6] = 0x3CFF; _KIi3_r[7] = 0xC725;
+test_expansion(_test_key3, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3, _KLi1_r, _KLi2_r, _KOi1_r, _KOi2_r, _KOi3_r, _KIi1_r, _KIi2_r, _KIi3_r);
+
+if (0x4592B0E78690F71B == _kasumi(0x62A540981BA6F9B7, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3))
+ printf("OK."); else printf("FAILED!");
+
+printf("\nKASUMI Test Set 4...");
+uint8_t _test_key4[] = {0x3A, 0x3B, 0x39, 0xB5, 0xC3, 0xF2, 0x37, 0x6D, 0x69, 0xF7, 0xD5, 0x46, 0xE5, 0xF8, 0x5D, 0x43};
+uint64_t I4 = 0xCA49C1C75771AB0B, i;
+_kasumi_key_expand(_test_key4, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3);
+
+for (i = 0; i < 50; i++)
+ I4 = _kasumi(I4, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3);
+
+if (0x738BAD4C4A690802 == I4) printf(" OK.\n"); else printf("FAILED!");
+
+
+uint8_t gamma[32];
+
+uint8_t _Key1[] = {0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xBC, 0x00, 0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xBC, 0x00},
+_gamma1[] = {0x88, 0x9E, 0xEA, 0xAF, 0x9E, 0xD1, 0xBA, 0x1A, 0xBB, 0xD8, 0x43, 0x62, 0x32, 0xE4, 0x57, 0x28, 0xD0, 0x1A, 0xA8, 0x91, 0x33, 0xDA, 0x73, 0xC1, 0x1E, 0xAB, 0x68, 0xB7, 0xD8, 0x9B, 0xC8, 0x41};
+_kasumi_kgcore(0xF, 0, 0x0024F20F, 0, _Key1, gamma, 228);
+printf ("KGCORE Test Set 1: %d\n", _compare_mem(gamma, _gamma1, 32));
+
+uint8_t _Key2[] = {0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48, 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48},
+_gamma2[] = {0xFB, 0x4D, 0x5F, 0xBC, 0xEE, 0x13, 0xA3, 0x33, 0x89, 0x28, 0x56, 0x86, 0xE9, 0xA5, 0xC9, 0x42, 0x40, 0xDE, 0x38, 0x15, 0x01, 0x15, 0xF1, 0x5F, 0x8D, 0x9D, 0x98, 0xB9, 0x1A, 0x94, 0xB2, 0x96};
+_kasumi_kgcore(0xF, 0, 0x00061272, 0, _Key2, gamma, 228);
+printf ("KGCORE Test Set 2: %d\n", _compare_mem(gamma, _gamma2, 32));
+
+uint8_t _Key3[] = {0xEF, 0xA8, 0xB2, 0x22, 0x9E, 0x72, 0x0C, 0x2A, 0xEF, 0xA8, 0xB2, 0x22, 0x9E, 0x72, 0x0C, 0x2A},
+_gamma3[] = {0x0E, 0x40, 0x15, 0x75, 0x5A, 0x33, 0x64, 0x69, 0xC3, 0xDD, 0x86, 0x80, 0xE3, 0x03, 0x5B, 0xC4, 0x19, 0xA7, 0x8A, 0xD3, 0x86, 0x2C, 0x10, 0x90, 0xC6, 0x8A, 0x39, 0x1F, 0xE8, 0xA6, 0xAD, 0xEB};
+_kasumi_kgcore(0xF, 0, 0x0033FD3F, 0, _Key3, gamma, 228);
+printf ("KGCORE Test Set 3: %d\n", _compare_mem(gamma, _gamma3, 32));
+
+uint8_t _Key4[] = {0x5A, 0xCB, 0x1D, 0x64, 0x4C, 0x0D, 0x51, 0x20, 0x4E, 0xA5, 0x5A, 0xCB, 0x1D, 0x64, 0x4C, 0x0D},
+_gamma4[] = {0xE0, 0x95, 0x30, 0x6A, 0xD5, 0x08, 0x6E, 0x2E, 0xAC, 0x7F, 0x31, 0x07, 0xDE, 0x4F, 0xA2, 0x2D, 0xC1, 0xDF, 0xC9, 0x7D, 0x5B, 0xC5, 0x66, 0x1D, 0xD6, 0x09, 0x6F, 0x47, 0x6A, 0xED, 0xC6, 0x4B};
+_kasumi_kgcore(0xF, 0, 0x00156B26, 0, _Key4, gamma, 228);
+printf ("KGCORE Test Set 4: %d\n", _compare_mem(gamma, _gamma4, 32));
+
+uint8_t _Key5[] = {0xD3, 0xC5, 0xD5, 0x92, 0x32, 0x7F, 0xB1, 0x1C, 0x40, 0x35, 0xC6, 0x68, 0x0A, 0xF8, 0xC6, 0xD1},
+_gamma5[] = {0xDC, 0xE6, 0x43, 0x62, 0xAB, 0x5F, 0x89, 0xC1, 0x1E, 0xF0, 0xB3, 0x05, 0x16, 0x65, 0x70, 0xF4, 0x88, 0x9D, 0x55, 0x11, 0xE9, 0xE3, 0x57, 0x5D, 0x06, 0x2B, 0x5C, 0xED, 0x60, 0x39, 0x50, 0x6A};
+_kasumi_kgcore(0xF, 0, 0x000A59B4, 0, _Key5, gamma, 228);
+printf ("KGCORE Test Set 5: %d\n", _compare_mem(gamma, _gamma5, 32));
+
+ return 0;
+}
diff --git a/tests/kasumi/kasumi_test.ok b/tests/kasumi/kasumi_test.ok
new file mode 100644
index 0000000..2c2af4c
--- /dev/null
+++ b/tests/kasumi/kasumi_test.ok
@@ -0,0 +1,10 @@
+testing KASUMI key expansion and encryption (ETSI TS 135 203):
+KASUMI Test Set 1... OK. OK.
+KASUMI Test Set 2... OK. OK.
+KASUMI Test Set 3... OK. OK.
+KASUMI Test Set 4... OK.
+KGCORE Test Set 1: 1
+KGCORE Test Set 2: 1
+KGCORE Test Set 3: 1
+KGCORE Test Set 4: 1
+KGCORE Test Set 5: 1
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 9124f25..7ce2ee8 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -9,6 +9,12 @@ cat $abs_srcdir/a5/a5_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/a5/a5_test], [0], [expout])
AT_CLEANUP
+AT_SETUP([kasumi])
+AT_KEYWORDS([kasumi])
+cat $abs_srcdir/kasumi/kasumi_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/kasumi/kasumi_test], [0], [expout])
+AT_CLEANUP
+
AT_SETUP([bits])
AT_KEYWORDS([bits])
cat $abs_srcdir/bits/bitrev_test.ok > expout
--
1.8.3.2
--------------030008030204080305010405--
1
0
---
.gitignore | 2 +
include/Makefile.am | 6 ++
include/osmocom/gsm/kasumi.h | 36 ++++++++
src/gsm/Makefile.am | 2 +-
src/gsm/kasumi.c | 193 +++++++++++++++++++++++++++++++++++++++++++
src/gsm/libosmogsm.map | 4 +
tests/Makefile.am | 7 +-
tests/kasumi/kasumi_test.c | 128 ++++++++++++++++++++++++++++
tests/kasumi/kasumi_test.ok | 10 +++
tests/testsuite.at | 6 ++
10 files changed, 391 insertions(+), 3 deletions(-)
create mode 100644 include/osmocom/gsm/kasumi.h
create mode 100644 src/gsm/kasumi.c
create mode 100644 tests/kasumi/kasumi_test.c
create mode 100644 tests/kasumi/kasumi_test.ok
diff --git a/.gitignore b/.gitignore
index c85d04d..1299028 100644
--- a/.gitignore
+++ b/.gitignore
@@ -55,6 +55,8 @@ tests/testsuite
tests/testsuite.dir/
tests/testsuite.log
+tests/utils/utils_test
+tests/kasumi/kasumi_test
tests/sms/sms_test
tests/timer/timer_test
tests/msgfile/msgfile_test
diff --git a/include/Makefile.am b/include/Makefile.am
index b035906..18011ff 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -2,6 +2,8 @@ nobase_include_HEADERS = \
osmocom/codec/codec.h \
osmocom/core/application.h \
osmocom/core/backtrace.h \
+ osmocom/core/bit32gen.h \
+ osmocom/core/bit64gen.h \
osmocom/core/bits.h \
osmocom/core/bitvec.h \
osmocom/core/conv.h \
@@ -107,6 +109,10 @@ endif
noinst_HEADERS = osmocom/core/timer_compat.h
+osmocom/core/bit%gen.h: osmocom/core/bitXXgen.h.tpl
+ $(AM_V_GEN)$(MKDIR_P) $(dir $@)
+ $(AM_V_GEN)sed -e's/XX/$*/g' $< > $@
+
osmocom/core/crc%gen.h: osmocom/core/crcXXgen.h.tpl
$(AM_V_GEN)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)sed -e's/XX/$*/g' $< > $@
diff --git a/include/osmocom/gsm/kasumi.h b/include/osmocom/gsm/kasumi.h
new file mode 100644
index 0000000..8479968
--- /dev/null
+++ b/include/osmocom/gsm/kasumi.h
@@ -0,0 +1,36 @@
+/*
+ * KASUMI header
+ *
+ * See kasumi.c for details
+ */
+
+#ifndef __KASUMI_H__
+#define __KASUMI_H__
+
+#include <stdint.h>
+
+/*
+ * Single iteration of KASUMI cipher
+*/
+uint64_t _kasumi(uint64_t P, uint16_t *KLi1, uint16_t *KLi2, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3);
+
+/*
+ * Implementation of the KGCORE algorithm (used by A5/3, A5/4, GEA3, GEA4 and ECSD)
+ *
+ * CA : uint8_t
+ * cb : uint8_t
+ * cc : uint32_t
+ * cd : uint8_t
+ * ck : uint8_t [8]
+ * co : uint8_t [output, cl-dependent]
+ * cl : uint16_t
+ */
+void _kasumi_kgcore(uint8_t CA, uint8_t cb, uint32_t cc, uint8_t cd, const uint8_t *ck, uint8_t *co, uint16_t cl);
+
+/*! \brief Expand key into set of subkeys
+ * \param[in] key (128 bits) as array of bytes
+ * \param[out] arrays of round-specific subkeys - see TS 135 202 for details
+ */
+void _kasumi_key_expand(const uint8_t *key, uint16_t *KLi1, uint16_t *KLi2, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3);
+
+#endif /* __KASUMI_H__ */
diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am
index 3162a7f..8ccbaec 100644
--- a/src/gsm/Makefile.am
+++ b/src/gsm/Makefile.am
@@ -15,7 +15,7 @@ libosmogsm_la_SOURCES = a5.c rxlev_stat.c tlv_parser.c comp128.c comp128v23.c \
gsm_utils.c rsl.c gsm48.c gsm48_ie.c gsm0808.c sysinfo.c \
gprs_cipher_core.c gsm0480.c abis_nm.c gsm0502.c \
gsm0411_utils.c gsm0411_smc.c gsm0411_smr.c \
- lapd_core.c lapdm.c \
+ lapd_core.c lapdm.c kasumi.c \
auth_core.c auth_comp128v1.c auth_comp128v23.c \
auth_milenage.c milenage/aes-encblock.c \
milenage/aes-internal.c milenage/aes-internal-enc.c \
diff --git a/src/gsm/kasumi.c b/src/gsm/kasumi.c
new file mode 100644
index 0000000..9900e05
--- /dev/null
+++ b/src/gsm/kasumi.c
@@ -0,0 +1,193 @@
+/* Kasumi cipher and KGcore functions */
+
+/* (C) 2013 by Max <Max.Suraev(a)fairwaves.ru>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <stdint.h>
+#include <osmocom/core/bits.h>
+#include <osmocom/gsm/kasumi.h>
+
+static uint16_t
+_kasumi_FI(uint16_t I, uint16_t skey)
+{
+ static uint16_t S7[] = {
+ 54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18, 123, 33,
+ 55, 113, 39, 114, 21, 67, 65, 12, 47, 73, 46, 27, 25, 111, 124, 81,
+ 53, 9, 121, 79, 52, 60, 58, 48, 101, 127, 40, 120, 104, 70, 71, 43,
+ 20, 122, 72, 61, 23, 109, 13, 100, 77, 1, 16, 7, 82, 10, 105, 98,
+ 117, 116, 76, 11, 89, 106, 0,125,118, 99, 86, 69, 30, 57, 126, 87,
+ 112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66,
+ 102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29, 115, 44,
+ 64, 107, 108, 24, 110, 83, 36, 78, 42, 19, 15, 41, 88, 119, 59, 3
+ };
+ static uint16_t S9[] = {
+ 167, 239, 161, 379, 391, 334, 9, 338, 38, 226, 48, 358, 452, 385, 90, 397,
+ 183, 253, 147, 331, 415, 340, 51, 362, 306, 500, 262, 82, 216, 159, 356, 177,
+ 175, 241, 489, 37, 206, 17, 0, 333, 44, 254, 378, 58, 143, 220, 81, 400,
+ 95, 3, 315, 245, 54, 235, 218, 405, 472, 264, 172, 494, 371, 290, 399, 76,
+ 165, 197, 395, 121, 257, 480, 423, 212, 240, 28, 462, 176, 406, 507, 288, 223,
+ 501, 407, 249, 265, 89, 186, 221, 428,164, 74, 440, 196, 458, 421, 350, 163,
+ 232, 158, 134, 354, 13, 250, 491, 142,191, 69, 193, 425, 152, 227, 366, 135,
+ 344, 300, 276, 242, 437, 320, 113, 278, 11, 243, 87, 317, 36, 93, 496, 27,
+ 487, 446, 482, 41, 68, 156, 457, 131, 326, 403, 339, 20, 39, 115, 442, 124,
+ 475, 384, 508, 53, 112, 170, 479, 151, 126, 169, 73, 268, 279, 321, 168, 364,
+ 363, 292, 46, 499, 393, 327, 324, 24, 456, 267, 157, 460, 488, 426, 309, 229,
+ 439, 506, 208, 271, 349, 401, 434, 236, 16, 209, 359, 52, 56, 120, 199, 277,
+ 465, 416, 252, 287, 246, 6, 83, 305, 420, 345, 153,502, 65, 61, 244, 282,
+ 173, 222, 418, 67, 386, 368, 261, 101, 476, 291, 195,430, 49, 79, 166, 330,
+ 280, 383, 373, 128, 382, 408, 155, 495, 367, 388, 274, 107, 459, 417, 62, 454,
+ 132, 225, 203, 316, 234, 14, 301, 91, 503, 286, 424, 211, 347, 307, 140, 374,
+ 35, 103, 125, 427, 19, 214, 453, 146, 498, 314, 444, 230, 256, 329, 198, 285,
+ 50, 116, 78, 410, 10, 205, 510, 171, 231, 45, 139, 467, 29, 86, 505, 32,
+ 72, 26, 342, 150, 313, 490, 431, 238, 411, 325, 149, 473, 40, 119, 174, 355,
+ 185, 233, 389, 71, 448, 273, 372, 55, 110, 178, 322, 12, 469, 392, 369, 190,
+ 1, 109, 375, 137, 181, 88, 75, 308, 260, 484, 98, 272, 370, 275, 412, 111,
+ 336, 318, 4, 504, 492, 259, 304, 77, 337, 435, 21, 357, 303, 332, 483, 18,
+ 47, 85, 25, 497, 474, 289, 100, 269, 296, 478, 270, 106, 31, 104, 433, 84,
+ 414, 486, 394, 96, 99, 154, 511, 148, 413, 361, 409, 255, 162, 215, 302, 201,
+ 266, 351, 343, 144, 441, 365, 108, 298, 251, 34, 182, 509, 138, 210, 335, 133,
+ 311, 352, 328, 141, 396, 346, 123, 319, 450, 281, 429, 228, 443, 481, 92, 404,
+ 485, 422, 248, 297, 23, 213, 130, 466, 22, 217, 283, 70, 294, 360, 419, 127,
+ 312, 377, 7, 468, 194, 2, 117, 295, 463, 258, 224, 447, 247, 187, 80, 398,
+ 284, 353, 105, 390, 299, 471, 470, 184, 57, 200, 348, 63, 204, 188, 33, 451,
+ 97, 30, 310, 219, 94, 160, 129, 493, 64, 179, 263, 102, 189, 207, 114, 402,
+ 438, 477, 387, 122, 192, 42, 381, 5, 145, 118, 180, 449, 293, 323, 136, 380,
+ 43, 66, 60, 455, 341, 445, 202, 432, 8, 237, 15, 376, 436, 464, 59, 461
+ };
+ uint16_t L, R;
+
+ /* Split 16 bit input into two unequal halves: 9 and 7 bits, same for subkey */
+ L = I >> 7; /* take 9 bits */
+ R = I & 0x7F; /* take 7 bits */
+
+ L = S9[L] ^ R;
+ R = S7[R] ^ (L & 0x7F);
+
+ L ^= (skey & 0x1FF);
+ R ^= (skey >> 9);
+
+ L = S9[L] ^ R;
+ R = S7[R] ^ (L & 0x7F);
+
+ return (R << 9) + L;
+}
+
+static uint32_t
+_kasumi_FO(uint32_t I, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3, unsigned i)
+{
+ uint16_t L = I >> 16, R = I; /* Split 32 bit input into Left and Right parts */
+
+ L ^= KOi1[i];
+ L = _kasumi_FI(L, KIi1[i]);
+ L ^= R;
+
+ R ^= KOi2[i];
+ R = _kasumi_FI(R, KIi2[i]);
+ R ^= L;
+
+ L ^= KOi3[i];
+ L = _kasumi_FI(L, KIi3[i]);
+ L ^= R;
+
+ return (((uint32_t)R) << 16) + L;
+}
+
+static uint32_t
+_kasumi_FL(uint32_t I, uint16_t *KLi1, uint16_t *KLi2, unsigned i)
+{
+ uint16_t L = I >> 16, R = I, tmp; /* Split 32 bit input into Left and Right parts */
+
+ tmp = L & KLi1[i];
+ R ^= rol16(tmp, 1);
+
+ tmp = R | KLi2[i];
+ L ^= rol16(tmp, 1);
+
+ return (((uint32_t)L) << 16) + R;
+}
+
+uint64_t
+_kasumi(uint64_t P, uint16_t *KLi1, uint16_t *KLi2, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3)
+{
+ uint32_t i, L = P >> 32, R = P; /* Split 64 bit input into Left and Right parts */
+
+ for (i = 0; i < 8; i++)
+ {
+ R ^= _kasumi_FO(_kasumi_FL(L, KLi1, KLi2, i), KOi1, KOi2, KOi3, KIi1, KIi2, KIi3, i); /* odd round */
+ i++;
+ L ^= _kasumi_FL(_kasumi_FO(R, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3, i), KLi1, KLi2, i); /* even round */
+ }
+ return (((uint64_t)L) << 32) + R; /* Concatenate Left and Right 32 bits into 64 bit ciphertext */
+}
+
+/*! \brief Expand key into set of subkeys
+ * \param[in] key (128 bits) as array of bytes
+ * \param[out] arrays of round-specific subkeys - see TS 135 202 for details
+ */
+void
+_kasumi_key_expand(const uint8_t *key, uint16_t *KLi1, uint16_t *KLi2, uint16_t *KOi1, uint16_t *KOi2, uint16_t *KOi3, uint16_t *KIi1, uint16_t *KIi2, uint16_t *KIi3)
+{
+ uint16_t i, C[] = { 0x0123, 0x4567, 0x89AB, 0xCDEF, 0xFEDC, 0xBA98, 0x7654, 0x3210 };
+
+ for (i = 0; i < 8; i++) /* Work with 16 bit subkeys and create prime subkeys */
+ {
+ C[i] ^= osmo_load16be(key + i * 2);
+ }
+ /* C[] now stores K-prime[] */
+ for (i = 0; i < 8; i++) /* Create round-specific subkeys */
+ {
+ KLi1[i] = rol16(osmo_load16be(key + i * 2), 1);
+ KLi2[i] = C[(i + 2) & 0x7];
+
+ KOi1[i] = rol16(osmo_load16be(key + ((2 * (i + 1)) & 0xE)), 5);
+ KOi2[i] = rol16(osmo_load16be(key + ((2 * (i + 5)) & 0xE)), 8);
+ KOi3[i] = rol16(osmo_load16be(key + ((2 * (i + 6)) & 0xE)), 13);
+
+ KIi1[i] = C[(i + 4) & 0x7];
+ KIi2[i] = C[(i + 3) & 0x7];
+ KIi3[i] = C[(i + 7) & 0x7];
+ }
+}
+
+void
+_kasumi_kgcore(uint8_t CA, uint8_t cb, uint32_t cc, uint8_t cd, const uint8_t *ck, uint8_t *co, uint16_t cl)
+{
+ uint16_t KLi1[8], KLi2[8], KOi1[8], KOi2[8], KOi3[8], KIi1[8], KIi2[8], KIi3[8], i;
+ uint64_t A = ((uint64_t)cc) << 32, BLK = 0, _ca = ((uint64_t)CA << 16) ;
+ A |= _ca;
+ _ca = (uint64_t)((cb << 3) | (cd << 2)) << 24;
+ A |= _ca;
+ /* Register loading complete: see TR 55.919 8.2 and TS 55.216 3.2 */
+
+ uint8_t ck_km[16];
+ for (i = 0; i < 16; i++) ck_km[i] = ck[i] ^ 0x55; /* Modified key established */
+
+ /* preliminary round with modified key */
+ _kasumi_key_expand(ck_km, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
+ A = _kasumi(A, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
+
+ /* Run Kasumi in OFB to obtain enough data for gamma. */
+ _kasumi_key_expand(ck, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
+ for (i = 0; i < cl / 64 + 1; i++) /* i is a block counter */
+ {
+ BLK = _kasumi(A ^ i ^ BLK, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
+ osmo_store64be(BLK, co + (i * 8));
+ }
+}
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 9d15d66..3a4a643 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -196,6 +196,10 @@ osmo_a5;
osmo_a5_1;
osmo_a5_2;
+_kasumi;
+_kasumi_key_expand;
+_kasumi_kgcore;
+
osmo_auth_alg_name;
osmo_auth_alg_parse;
osmo_auth_gen_vec;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index c6216d5..ddc13dc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,7 +4,7 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \
smscb/smscb_test bits/bitrev_test a5/a5_test \
conv/conv_test auth/milenage_test lapd/lapd_test \
gsm0808/gsm0808_test gsm0408/gsm0408_test \
- gb/bssgp_fc_test gb/gprs_ns_test \
+ gb/bssgp_fc_test gb/gprs_ns_test kasumi/kasumi_test \
logging/logging_test fr/fr_test \
loggingrb/loggingrb_test strrb/strrb_test \
vty/vty_test comp128/comp128_test utils/utils_test
@@ -19,6 +19,9 @@ utils_utils_test_LDADD = $(top_builddir)/src/libosmocore.la
a5_a5_test_SOURCES = a5/a5_test.c
a5_a5_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
+kasumi_kasumi_test_SOURCES = kasumi/kasumi_test.c
+kasumi_kasumi_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
+
comp128_comp128_test_SOURCES = comp128/comp128_test.c
comp128_comp128_test_LDADD = $(top_builddir)/src/libosmocore.la $(top_builddir)/src/gsm/libosmogsm.la
@@ -102,7 +105,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
lapd/lapd_test.ok gsm0408/gsm0408_test.ok \
gsm0808/gsm0808_test.ok gb/bssgp_fc_tests.err \
gb/bssgp_fc_tests.ok gb/bssgp_fc_tests.sh \
- gb/gprs_ns_test.ok \
+ gb/gprs_ns_test.ok kasumi/kasumi_test.ok \
msgfile/msgfile_test.ok msgfile/msgconfig.cfg \
logging/logging_test.ok logging/logging_test.err \
fr/fr_test.ok loggingrb/logging_test.ok \
diff --git a/tests/kasumi/kasumi_test.c b/tests/kasumi/kasumi_test.c
new file mode 100644
index 0000000..fbe23a9
--- /dev/null
+++ b/tests/kasumi/kasumi_test.c
@@ -0,0 +1,128 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/gsm/kasumi.h>
+
+
+inline int _compare_mem(uint8_t * x, uint8_t * y, size_t len) {
+ if (0 != memcmp(x, y, len)) {
+ printf ("X: %s\t", osmo_hexdump_nospc(x, len));
+ printf ("Y: %s\n", osmo_hexdump_nospc(y, len));
+ return 0;
+ }
+ return 1;
+}
+
+inline static void test_expansion(uint8_t * test_key, uint16_t * _KLi1, uint16_t * _KLi2, uint16_t * _KOi1, uint16_t * _KOi2, uint16_t * _KOi3, uint16_t * _KIi1, uint16_t * _KIi2, uint16_t * _KIi3, uint16_t * _KLi1_r, uint16_t * _KLi2_r, uint16_t * _KOi1_r, uint16_t * _KOi2_r, uint16_t * _KOi3_r, uint16_t * _KIi1_r, uint16_t * _KIi2_r, uint16_t * _KIi3_r)
+{
+ _kasumi_key_expand(test_key, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3);
+ int passed = 1;
+ passed = _compare_mem((uint8_t *)_KLi1, (uint8_t *)_KLi1_r, 16);
+ passed = _compare_mem((uint8_t *)_KLi2, (uint8_t *)_KLi2_r, 16);
+ passed = _compare_mem((uint8_t *)_KOi1, (uint8_t *)_KOi1_r, 16);
+ passed = _compare_mem((uint8_t *)_KOi2, (uint8_t *)_KOi2_r, 16);
+ passed = _compare_mem((uint8_t *)_KOi3, (uint8_t *)_KOi3_r, 16);
+ passed = _compare_mem((uint8_t *)_KIi1, (uint8_t *)_KIi1_r, 16);
+ passed = _compare_mem((uint8_t *)_KIi2, (uint8_t *)_KIi2_r, 16);
+ passed = _compare_mem((uint8_t *)_KIi3, (uint8_t *)_KIi3_r, 16);
+ if (passed) printf(" OK. "); else printf("FAILED!");
+}
+
+int main(int argc, char **argv)
+{
+ uint16_t _KLi1[8], _KLi2[8], _KOi1[8], _KOi2[8], _KOi3[8], _KIi1[8], _KIi2[8], _KIi3[8], _KLi1_r[8], _KLi2_r[8], _KOi1_r[8], _KOi2_r[8], _KOi3_r[8], _KIi1_r[8], _KIi2_r[8], _KIi3_r[8];
+
+ printf("testing KASUMI key expansion and encryption (ETSI TS 135 203):\n");
+ printf("KASUMI Test Set 1...");
+
+uint8_t _test_key1[] = {0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00, 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48};
+_KLi1_r[0] = 0x57AC; _KLi1_r[1] = 0x8B3E; _KLi1_r[2] = 0x058B; _KLi1_r[3] = 0x6601; _KLi1_r[4] = 0x2A59; _KLi1_r[5] = 0x9220; _KLi1_r[6] = 0x9102; _KLi1_r[7] = 0xFE91;
+_KLi2_r[0] = 0x0B6E; _KLi2_r[1] = 0x7EEF; _KLi2_r[2] = 0x6BF0; _KLi2_r[3] = 0xF388; _KLi2_r[4] = 0x3ED5; _KLi2_r[5] = 0xCD58; _KLi2_r[6] = 0x2AF5; _KLi2_r[7] = 0x00F8;
+_KOi1_r[0] = 0xB3E8; _KOi1_r[1] = 0x58B0; _KOi1_r[2] = 0x6016; _KOi1_r[3] = 0xA592; _KOi1_r[4] = 0x2209; _KOi1_r[5] = 0x1029; _KOi1_r[6] = 0xE91F; _KOi1_r[7] = 0x7AC5;
+_KOi2_r[0] = 0x1049; _KOi2_r[1] = 0x8148; _KOi2_r[2] = 0x48FF; _KOi2_r[3] = 0xD62B; _KOi2_r[4] = 0x9F45; _KOi2_r[5] = 0xC582; _KOi2_r[6] = 0x00B3; _KOi2_r[7] = 0x2C95;
+_KOi3_r[0] = 0x2910; _KOi3_r[1] = 0x1FE9; _KOi3_r[2] = 0xC57A; _KOi3_r[3] = 0xE8B3; _KOi3_r[4] = 0xB058; _KOi3_r[5] = 0x1660; _KOi3_r[6] = 0x92A5; _KOi3_r[7] = 0x0922;
+_KIi1_r[0] = 0x6BF0; _KIi1_r[1] = 0xF388; _KIi1_r[2] = 0x3ED5; _KIi1_r[3] = 0xCD58; _KIi1_r[4] = 0x2AF5; _KIi1_r[5] = 0x00F8; _KIi1_r[6] = 0x0B6E; _KIi1_r[7] = 0x7EEF;
+_KIi2_r[0] = 0x7EEF; _KIi2_r[1] = 0x6BF0; _KIi2_r[2] = 0xF388; _KIi2_r[3] = 0x3ED5; _KIi2_r[4] = 0xCD58; _KIi2_r[5] = 0x2AF5; _KIi2_r[6] = 0x00F8; _KIi2_r[7] = 0x0B6E;
+_KIi3_r[0] = 0xCD58; _KIi3_r[1] = 0x2AF5; _KIi3_r[2] = 0x00F8; _KIi3_r[3] = 0x0B6E; _KIi3_r[4] = 0x7EEF; _KIi3_r[5] = 0x6BF0; _KIi3_r[6] = 0xF388; _KIi3_r[7] = 0x3ED5;
+test_expansion(_test_key1, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3, _KLi1_r, _KLi2_r, _KOi1_r, _KOi2_r, _KOi3_r, _KIi1_r, _KIi2_r, _KIi3_r);
+
+if (0xDF1F9B251C0BF45F == _kasumi(0xEA024714AD5C4D84, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3))
+ printf("OK."); else printf("FAILED!");
+
+printf("\nKASUMI Test Set 2...");
+
+uint8_t _test_key2[] = {0x8C, 0xE3, 0x3E, 0x2C, 0xC3, 0xC0, 0xB5, 0xFC, 0x1F, 0x3D, 0xE8, 0xA6, 0xDC, 0x66, 0xB1, 0xF3};
+_KLi1_r[0] = 0x19C7; _KLi1_r[1] = 0x7C58; _KLi1_r[2] = 0x8781; _KLi1_r[3] = 0x6BF9; _KLi1_r[4] = 0x3E7A; _KLi1_r[5] = 0xD14D; _KLi1_r[6] = 0xB8CD; _KLi1_r[7] = 0x63E7;
+_KLi2_r[0] = 0x4A6B; _KLi2_r[1] = 0x7813; _KLi2_r[2] = 0xE1E1; _KLi2_r[3] = 0x523E; _KLi2_r[4] = 0xAA32; _KLi2_r[5] = 0x83E3; _KLi2_r[6] = 0x8DC0; _KLi2_r[7] = 0x7B4B;
+_KOi1_r[0] = 0xC587; _KOi1_r[1] = 0x7818; _KOi1_r[2] = 0xBF96; _KOi1_r[3] = 0xE7A3; _KOi1_r[4] = 0x14DD; _KOi1_r[5] = 0x8CDB; _KOi1_r[6] = 0x3E76; _KOi1_r[7] = 0x9C71;
+_KOi2_r[0] = 0xA6E8; _KOi2_r[1] = 0x66DC; _KOi2_r[2] = 0xF3B1; _KOi2_r[3] = 0xE38C; _KOi2_r[4] = 0x2C3E; _KOi2_r[5] = 0xC0C3; _KOi2_r[6] = 0xFCB5; _KOi2_r[7] = 0x3D1F;
+_KOi3_r[0] = 0xDB8C; _KOi3_r[1] = 0x763E; _KOi3_r[2] = 0x719C; _KOi3_r[3] = 0x87C5; _KOi3_r[4] = 0x1878; _KOi3_r[5] = 0x96BF; _KOi3_r[6] = 0xA3E7; _KOi3_r[7] = 0xDD14;
+_KIi1_r[0] = 0xE1E1; _KIi1_r[1] = 0x523E; _KIi1_r[2] = 0xAA32; _KIi1_r[3] = 0x83E3; _KIi1_r[4] = 0x8DC0; _KIi1_r[5] = 0x7B4B; _KIi1_r[6] = 0x4A6B; _KIi1_r[7] = 0x7813;
+_KIi2_r[0] = 0x7813; _KIi2_r[1] = 0xE1E1; _KIi2_r[2] = 0x523E; _KIi2_r[3] = 0xAA32; _KIi2_r[4] = 0x83E3; _KIi2_r[5] = 0x8DC0; _KIi2_r[6] = 0x7B4B; _KIi2_r[7] = 0x4A6B;
+_KIi3_r[0] = 0x83E3; _KIi3_r[1] = 0x8DC0; _KIi3_r[2] = 0x7B4B; _KIi3_r[3] = 0x4A6B; _KIi3_r[4] = 0x7813; _KIi3_r[5] = 0xE1E1; _KIi3_r[6] = 0x523E; _KIi3_r[7] = 0xAA32;
+test_expansion(_test_key2, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3, _KLi1_r, _KLi2_r, _KOi1_r, _KOi2_r, _KOi3_r, _KIi1_r, _KIi2_r, _KIi3_r);
+
+if (0xDE551988CEB2F9B7 == _kasumi(0xD3C5D592327FB11C, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3))
+ printf("OK."); else printf("FAILED!");
+
+printf("\nKASUMI Test Set 3...");
+
+uint8_t _test_key3[] = {0x40, 0x35, 0xC6, 0x68, 0x0A, 0xF8, 0xC6, 0xD1, 0xA8, 0xFF, 0x86, 0x67, 0xB1, 0x71, 0x40, 0x13};
+_KLi1_r[0] = 0x806A; _KLi1_r[1] = 0x8CD1; _KLi1_r[2] = 0x15F0; _KLi1_r[3] = 0x8DA3; _KLi1_r[4] = 0x51FF; _KLi1_r[5] = 0x0CCF; _KLi1_r[6] = 0x62E3; _KLi1_r[7] = 0x8026;
+_KLi2_r[0] = 0x8353; _KLi2_r[1] = 0x0B3E; _KLi2_r[2] = 0x5623; _KLi2_r[3] = 0x3CFF; _KLi2_r[4] = 0xC725; _KLi2_r[5] = 0x7203; _KLi2_r[6] = 0x4116; _KLi2_r[7] = 0x830F;
+_KOi1_r[0] = 0xCD18; _KOi1_r[1] = 0x5F01; _KOi1_r[2] = 0xDA38; _KOi1_r[3] = 0x1FF5; _KOi1_r[4] = 0xCCF0; _KOi1_r[5] = 0x2E36; _KOi1_r[6] = 0x0268; _KOi1_r[7] = 0x06A8;
+_KOi2_r[0] = 0x6786; _KOi2_r[1] = 0x71B1; _KOi2_r[2] = 0x1340; _KOi2_r[3] = 0x3540; _KOi2_r[4] = 0x68C6; _KOi2_r[5] = 0xF80A; _KOi2_r[6] = 0xD1C6; _KOi2_r[7] = 0xFFA8;
+_KOi3_r[0] = 0x362E; _KOi3_r[1] = 0x6802; _KOi3_r[2] = 0xA806; _KOi3_r[3] = 0x18CD; _KOi3_r[4] = 0x015F; _KOi3_r[5] = 0x38DA; _KOi3_r[6] = 0xF51F; _KOi3_r[7] = 0xF0CC;
+_KIi1_r[0] = 0x5623; _KIi1_r[1] = 0x3CFF; _KIi1_r[2] = 0xC725; _KIi1_r[3] = 0x7203; _KIi1_r[4] = 0x4116; _KIi1_r[5] = 0x830F; _KIi1_r[6] = 0x8353; _KIi1_r[7] = 0x0B3E;
+_KIi2_r[0] = 0x0B3E; _KIi2_r[1] = 0x5623; _KIi2_r[2] = 0x3CFF; _KIi2_r[3] = 0xC725; _KIi2_r[4] = 0x7203; _KIi2_r[5] = 0x4116; _KIi2_r[6] = 0x830F; _KIi2_r[7] = 0x8353;
+_KIi3_r[0] = 0x7203; _KIi3_r[1] = 0x4116; _KIi3_r[2] = 0x830F; _KIi3_r[3] = 0x8353; _KIi3_r[4] = 0x0B3E; _KIi3_r[5] = 0x5623; _KIi3_r[6] = 0x3CFF; _KIi3_r[7] = 0xC725;
+test_expansion(_test_key3, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3, _KLi1_r, _KLi2_r, _KOi1_r, _KOi2_r, _KOi3_r, _KIi1_r, _KIi2_r, _KIi3_r);
+
+if (0x4592B0E78690F71B == _kasumi(0x62A540981BA6F9B7, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3))
+ printf("OK."); else printf("FAILED!");
+
+printf("\nKASUMI Test Set 4...");
+uint8_t _test_key4[] = {0x3A, 0x3B, 0x39, 0xB5, 0xC3, 0xF2, 0x37, 0x6D, 0x69, 0xF7, 0xD5, 0x46, 0xE5, 0xF8, 0x5D, 0x43};
+uint64_t I4 = 0xCA49C1C75771AB0B, i;
+_kasumi_key_expand(_test_key4, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3);
+
+for (i = 0; i < 50; i++)
+ I4 = _kasumi(I4, _KLi1, _KLi2, _KOi1, _KOi2, _KOi3, _KIi1, _KIi2, _KIi3);
+
+if (0x738BAD4C4A690802 == I4) printf(" OK.\n"); else printf("FAILED!");
+
+
+uint8_t gamma[32];
+
+uint8_t _Key1[] = {0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xBC, 0x00, 0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xBC, 0x00},
+_gamma1[] = {0x88, 0x9E, 0xEA, 0xAF, 0x9E, 0xD1, 0xBA, 0x1A, 0xBB, 0xD8, 0x43, 0x62, 0x32, 0xE4, 0x57, 0x28, 0xD0, 0x1A, 0xA8, 0x91, 0x33, 0xDA, 0x73, 0xC1, 0x1E, 0xAB, 0x68, 0xB7, 0xD8, 0x9B, 0xC8, 0x41};
+_kasumi_kgcore(0xF, 0, 0x0024F20F, 0, _Key1, gamma, 228);
+printf ("KGCORE Test Set 1: %d\n", _compare_mem(gamma, _gamma1, 32));
+
+uint8_t _Key2[] = {0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48, 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48},
+_gamma2[] = {0xFB, 0x4D, 0x5F, 0xBC, 0xEE, 0x13, 0xA3, 0x33, 0x89, 0x28, 0x56, 0x86, 0xE9, 0xA5, 0xC9, 0x42, 0x40, 0xDE, 0x38, 0x15, 0x01, 0x15, 0xF1, 0x5F, 0x8D, 0x9D, 0x98, 0xB9, 0x1A, 0x94, 0xB2, 0x96};
+_kasumi_kgcore(0xF, 0, 0x00061272, 0, _Key2, gamma, 228);
+printf ("KGCORE Test Set 2: %d\n", _compare_mem(gamma, _gamma2, 32));
+
+uint8_t _Key3[] = {0xEF, 0xA8, 0xB2, 0x22, 0x9E, 0x72, 0x0C, 0x2A, 0xEF, 0xA8, 0xB2, 0x22, 0x9E, 0x72, 0x0C, 0x2A},
+_gamma3[] = {0x0E, 0x40, 0x15, 0x75, 0x5A, 0x33, 0x64, 0x69, 0xC3, 0xDD, 0x86, 0x80, 0xE3, 0x03, 0x5B, 0xC4, 0x19, 0xA7, 0x8A, 0xD3, 0x86, 0x2C, 0x10, 0x90, 0xC6, 0x8A, 0x39, 0x1F, 0xE8, 0xA6, 0xAD, 0xEB};
+_kasumi_kgcore(0xF, 0, 0x0033FD3F, 0, _Key3, gamma, 228);
+printf ("KGCORE Test Set 3: %d\n", _compare_mem(gamma, _gamma3, 32));
+
+uint8_t _Key4[] = {0x5A, 0xCB, 0x1D, 0x64, 0x4C, 0x0D, 0x51, 0x20, 0x4E, 0xA5, 0x5A, 0xCB, 0x1D, 0x64, 0x4C, 0x0D},
+_gamma4[] = {0xE0, 0x95, 0x30, 0x6A, 0xD5, 0x08, 0x6E, 0x2E, 0xAC, 0x7F, 0x31, 0x07, 0xDE, 0x4F, 0xA2, 0x2D, 0xC1, 0xDF, 0xC9, 0x7D, 0x5B, 0xC5, 0x66, 0x1D, 0xD6, 0x09, 0x6F, 0x47, 0x6A, 0xED, 0xC6, 0x4B};
+_kasumi_kgcore(0xF, 0, 0x00156B26, 0, _Key4, gamma, 228);
+printf ("KGCORE Test Set 4: %d\n", _compare_mem(gamma, _gamma4, 32));
+
+uint8_t _Key5[] = {0xD3, 0xC5, 0xD5, 0x92, 0x32, 0x7F, 0xB1, 0x1C, 0x40, 0x35, 0xC6, 0x68, 0x0A, 0xF8, 0xC6, 0xD1},
+_gamma5[] = {0xDC, 0xE6, 0x43, 0x62, 0xAB, 0x5F, 0x89, 0xC1, 0x1E, 0xF0, 0xB3, 0x05, 0x16, 0x65, 0x70, 0xF4, 0x88, 0x9D, 0x55, 0x11, 0xE9, 0xE3, 0x57, 0x5D, 0x06, 0x2B, 0x5C, 0xED, 0x60, 0x39, 0x50, 0x6A};
+_kasumi_kgcore(0xF, 0, 0x000A59B4, 0, _Key5, gamma, 228);
+printf ("KGCORE Test Set 5: %d\n", _compare_mem(gamma, _gamma5, 32));
+
+ return 0;
+}
diff --git a/tests/kasumi/kasumi_test.ok b/tests/kasumi/kasumi_test.ok
new file mode 100644
index 0000000..2c2af4c
--- /dev/null
+++ b/tests/kasumi/kasumi_test.ok
@@ -0,0 +1,10 @@
+testing KASUMI key expansion and encryption (ETSI TS 135 203):
+KASUMI Test Set 1... OK. OK.
+KASUMI Test Set 2... OK. OK.
+KASUMI Test Set 3... OK. OK.
+KASUMI Test Set 4... OK.
+KGCORE Test Set 1: 1
+KGCORE Test Set 2: 1
+KGCORE Test Set 3: 1
+KGCORE Test Set 4: 1
+KGCORE Test Set 5: 1
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 9124f25..7ce2ee8 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -9,6 +9,12 @@ cat $abs_srcdir/a5/a5_test.ok > expout
AT_CHECK([$abs_top_builddir/tests/a5/a5_test], [0], [expout])
AT_CLEANUP
+AT_SETUP([kasumi])
+AT_KEYWORDS([kasumi])
+cat $abs_srcdir/kasumi/kasumi_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/kasumi/kasumi_test], [0], [expout])
+AT_CLEANUP
+
AT_SETUP([bits])
AT_KEYWORDS([bits])
cat $abs_srcdir/bits/bitrev_test.ok > expout
--
1.8.3.2
--------------060004070705090302070204--
1
0