AKA socket SIM interface » History » Version 2
laforge, 03/25/2022 11:25 AM
toc, explain providers/consumers
1 | 1 | laforge | h1. AKA socket SIM interface |
---|---|---|---|
2 | |||
3 | 2 | laforge | {{>toc}} |
4 | |||
5 | This is an interface we are creating to communicate the 3G-AKA (authentication and key agreement) between clients (consumders) and servers (providers) |
||
6 | |||
7 | A _provider_ interfaces in some way with a USIM card, for example |
||
8 | * via pcsc-lite to a USIM inserted in a CCID reader |
||
9 | * via AT-commands (AT+CSIM) to a USIM inserted in a cellular modem |
||
10 | |||
11 | A _consumer_ interfaces in some wayt with a 3GPP cellular network, for example |
||
12 | * [[doubango]] when authenticating against an IMS Core (P-CSCF) in [[VoLTE]] and [[VoWiFi]] |
||
13 | * strongswan IPsec client when establishing the SWu interface towards the ePDG in [[VoWiFi]] |
||
14 | |||
15 | It could possibly also be used by other projects like srsUE, OsmocomBB, ... |
||
16 | |||
17 | 1 | laforge | |
18 | h2. Protocol / Data structures |
||
19 | |||
20 | The interface is based on a unix domain socke with a very simplistic binary message format as outlined below: |
||
21 | |||
22 | <pre> |
||
23 | #pragma once |
||
24 | |||
25 | /* Definitions regarding the "AKA authentication socket", a mechanism |
||
26 | * by which various client programs can request the 3G AKA procedure to be performed |
||
27 | * against a card. |
||
28 | * |
||
29 | * This is intended as a very simple, low-level interface. Security/access control is |
||
30 | * managed by file system permissions, i.e. which processes can access the unix domain |
||
31 | * socket path. |
||
32 | * |
||
33 | * (C) 2022 by Harald Welte <laforge@osmocom.org> |
||
34 | */ |
||
35 | |||
36 | #include <stdint.h> |
||
37 | |||
38 | #define AKASOCK_MAGIC 0x51FC43D5 |
||
39 | #define AKASOCK_VERSION 1 |
||
40 | |||
41 | enum akasock_msg_type { |
||
42 | AKASOCK_MSGT_AKA_REQ = 0x01, |
||
43 | AKASOCK_MSGT_AKA_RES_OK = 0x02, |
||
44 | AKASOCK_MSGT_AKA_RES_SYNC = 0x03, |
||
45 | AKASOCK_MSGT_AKA_RES_ERR = 0x04, |
||
46 | AKASOCK_MSGT_IMSI_REQ = 0x05, |
||
47 | AKASOCK_MSGT_IMSI_RES = 0x06, |
||
48 | }; |
||
49 | |||
50 | struct akasock_msg_hdr { |
||
51 | uint32_t magic; /* AKASOCK_MAGIC */ |
||
52 | uint8_t version; /* AKASOCK_VERSION */ |
||
53 | uint8_t msg_type; /* akasock_msg_type */ |
||
54 | uint8_t channel; /* 0=first SIM, 1=2nd, ... */ |
||
55 | uint8_t tag; /* to match request with response */ |
||
56 | uint8_t data[0]; /* any of the structs below */ |
||
57 | } __attribute__ ((packed)); |
||
58 | |||
59 | struct akasock_aka_req { |
||
60 | uint8_t isim_instead_of_usim; /* 0=USIM, 1=ISIM */ |
||
61 | uint8_t rand_len; |
||
62 | uint8_t rand[32]; |
||
63 | uint8_t autn_len; |
||
64 | uint8_t autn[32]; |
||
65 | } __attribute__ ((packed)); |
||
66 | |||
67 | struct akasock_aka_resp_success { |
||
68 | uint8_t res_len; |
||
69 | uint8_t res[32]; |
||
70 | uint8_t ck_len; |
||
71 | uint8_t ck[32]; |
||
72 | uint8_t ik_len; |
||
73 | uint8_t ik[32]; |
||
74 | uint8_t kc_len; |
||
75 | uint8_t kc[32]; |
||
76 | } __attribute__ ((packed)); |
||
77 | |||
78 | struct akasock_aka_resp_sync { |
||
79 | uint8_t auts_len; |
||
80 | uint8_t auts[32]; |
||
81 | } __attribute__ ((packed)); |
||
82 | |||
83 | struct akasock_aka_resp_err { |
||
84 | uint16_t sw; |
||
85 | } __attribute__ ((packed)); |
||
86 | |||
87 | struct akasock_imsi_resp { |
||
88 | uint8_t imsi_len; |
||
89 | char imsi[32]; /* IMSI As ASCII string */ |
||
90 | } __attribute__ ((packed)); |
||
91 | </pre> |
||
92 | |||
93 | |||
94 | h2. Message flow |
||
95 | |||
96 | The client programs (doubango, strongswan, ...) will typically perform the following exchanges: |
||
97 | |||
98 | {{mscgen_link |
||
99 | msc { |
||
100 | hscale=2; |
||
101 | pcscf [label="P-CSCF"], client [label="AKASOCK client (e.g. doubango)"], server [label="AKASOCK server"], sim [label="SIM card"]; |
||
102 | client => server [label="AKASOCK_MSGT_IMSI_REQ"]; |
||
103 | server => sim [label="SELECT ADF.USIM/EF.IMSI"]; |
||
104 | server => sim [label="READ BINARY"]; |
||
105 | server box server [label="convert from binary to string"]; |
||
106 | client <= server [label="AKASOCK_MSGT_IMSI_RES"]; |
||
107 | client box client [label="Client can now start first SIP REGISTER with IPUI=IMSI"]; |
||
108 | pcscf <= client [label="SIP REGISTER (first one)"]; |
||
109 | pcscf => client [label="Unauthorized (contains RAND,AUTN)"]; |
||
110 | client => server [label="AKASOCK_MSGT_AKA_REQ (RAND, AUTN)"]; |
||
111 | client => sim [label="AUTHENTICATE"]; |
||
112 | client <= sim [label="Result"]; |
||
113 | client <= server [label="AKASOCK_MSGT_AKA_RES_OK (RES, CK, IK)"]; |
||
114 | client box client [label="Derive IPsec keys from CK, IK, create SAs"]; |
||
115 | pcscf <= client [label="Start new TCP connection inside IPsec SA"]; |
||
116 | pcscf <= client [label="SIP REGISTER (second, with RES)"]; |
||
117 | pcscf box pcscf [label="Verify RES"]; |
||
118 | pcscf => client [label="200 OK"]; |
||
119 | } |
||
120 | }} |
||
121 | |||
122 | AKA socket |