Harald Welte | ad41863 | 2012-09-10 10:49:59 +0200 | [diff] [blame] | 1 | /* 3GPP USIM specific structures / routines */ |
| 2 | /* |
| 3 | * (C) 2012 by Harald Welte <laforge@gnumonks.org> |
| 4 | * |
| 5 | * All Rights Reserved |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | * |
| 12 | * This program is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | * GNU General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License along |
| 18 | * with this program; if not, write to the Free Software Foundation, Inc., |
| 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 20 | * |
| 21 | */ |
| 22 | |
Harald Welte | d54c2ee | 2012-01-17 18:25:50 +0100 | [diff] [blame] | 23 | |
| 24 | #include <errno.h> |
| 25 | #include <string.h> |
| 26 | |
| 27 | #include <osmocom/sim/sim.h> |
| 28 | #include <osmocom/core/talloc.h> |
| 29 | #include <osmocom/gsm/gsm48.h> |
| 30 | |
| 31 | #include "sim_int.h" |
| 32 | #include "gsm_int.h" |
| 33 | |
| 34 | /* TS 31.102 Version 7.7.0 / Chapoter 7.3 */ |
| 35 | const struct osim_card_sw ts31_102_sw[] = { |
| 36 | { |
| 37 | 0x9862, 0xffff, SW_TYPE_STR, SW_CLS_ERROR, |
| 38 | .u.str = "Security management - Authentication error, incorrect MAC", |
| 39 | }, { |
| 40 | 0x9864, 0xffff, SW_TYPE_STR, SW_CLS_ERROR, |
| 41 | .u.str = "Security management - Authentication error, security context not supported", |
| 42 | }, { |
| 43 | 0x9865, 0xffff, SW_TYPE_STR, SW_CLS_ERROR, |
| 44 | .u.str = "Security management - Key freshness error", |
| 45 | }, |
| 46 | OSIM_CARD_SW_LAST |
| 47 | }; |
| 48 | |
| 49 | static const struct osim_card_sw *usim_card_sws[] = { |
| 50 | ts31_102_sw, |
| 51 | ts102221_uicc_sw, |
| 52 | NULL |
| 53 | }; |
| 54 | |
| 55 | |
| 56 | static int default_decode(struct osim_decoded_data *dd, |
| 57 | const struct osim_file_desc *desc, |
| 58 | int len, uint8_t *data) |
| 59 | { |
| 60 | struct osim_decoded_element *elem; |
| 61 | |
| 62 | elem = element_alloc(dd, "Unknown Payload", ELEM_T_BYTES, ELEM_REPR_HEX); |
| 63 | elem->u.buf = talloc_memdup(elem, data, len); |
| 64 | |
| 65 | return 0; |
| 66 | } |
| 67 | |
| 68 | /* TS 102 221 Chapter 13.1 */ |
| 69 | static const struct osim_file_desc uicc_ef_in_mf[] = { |
| 70 | EF_LIN_FIX_N(0x2f00, "EF.DIR", 0, |
| 71 | "Application directory"), |
| 72 | EF_TRANSP_N(0x2FE2, "EF.ICCID", 0, |
| 73 | "ICC Identification"), |
| 74 | EF_TRANSP_N(0x2F05, "EF.PL", 0, |
| 75 | "Preferred Languages"), |
| 76 | EF_LIN_FIX_N(0x2F06, "EF.ARR", F_OPTIONAL, |
| 77 | "Access Rule Reference"), |
| 78 | }; |
| 79 | |
| 80 | static const struct osim_file_desc usim_ef_in_df_gsm_access[] = { |
| 81 | EF_TRANSP_N(0x4f20, "EF.Kc", 0, |
| 82 | "Ciphering Key Kc"), |
| 83 | EF_TRANSP_N(0x4f52, "EF.KcGPRS", 0, |
| 84 | "GPRS Ciphering key KcGPRS"), |
| 85 | EF_TRANSP_N(0x4f63, "EF.CPBCCH", F_OPTIONAL, |
| 86 | "CPBCCH Information"), |
| 87 | EF_TRANSP_N(0x4f64, "EF.invSCAN", F_OPTIONAL, |
| 88 | "Investigation Scan"), |
| 89 | }; |
| 90 | |
| 91 | /* 31.102 Chapter 4.2 */ |
| 92 | static const struct osim_file_desc usim_ef_in_adf_usim[] = { |
| 93 | EF_TRANSP(0x6F05, "EF.LI", 0, |
| 94 | "Language Indication", &gsm_lp_decode, NULL), |
| 95 | EF_TRANSP(0x6F07, "EF.IMSI", 0, |
| 96 | "IMSI", &gsm_imsi_decode, NULL), |
| 97 | EF_TRANSP_N(0x6F08, "EF.Keys", 0, |
| 98 | "Ciphering and Integrity Keys"), |
| 99 | EF_TRANSP_N(0x6F09, "EF.KeysPS", 0, |
| 100 | "Ciphering and Integrity Keys for Packet Switched domain"), |
| 101 | EF_TRANSP_N(0x6F60, "EF.PLMNwAcT", F_OPTIONAL, |
| 102 | "User controlled PLMN Selector with Access Technology"), |
| 103 | EF_TRANSP(0x6F31, "EF.HPPLMN", 0, |
| 104 | "Higher Priority PLMN search period", &gsm_hpplmn_decode, NULL), |
| 105 | EF_TRANSP_N(0x6F37, "EF.ACMmax", F_OPTIONAL, |
| 106 | "ACM maximum value"), |
| 107 | EF_TRANSP_N(0x6F38, "EF.UST", 0, |
| 108 | "USIM Service Table"), |
| 109 | EF_CYCLIC_N(0x6F39, "EF.ACM", F_OPTIONAL, |
| 110 | "Accumulated call meter"), |
| 111 | EF_TRANSP_N(0x6F3E, "EF.GID1", F_OPTIONAL, |
| 112 | "Group Identifier Level 1"), |
| 113 | EF_TRANSP_N(0x6F3F, "EF.GID2", F_OPTIONAL, |
| 114 | "Group Identifier Level 2"), |
| 115 | EF_TRANSP_N(0x6F46, "EF.SPN", F_OPTIONAL, |
| 116 | "Service Provider Name"), |
| 117 | EF_TRANSP_N(0x6F41, "EF.PUCT", F_OPTIONAL, |
| 118 | "Price per unit and currency table"), |
| 119 | EF_TRANSP_N(0x6F45, "EF.CBMI", F_OPTIONAL, |
| 120 | "Cell broadcast massage identifier selection"), |
| 121 | EF_TRANSP_N(0x6F78, "EF.ACC", 0, |
| 122 | "Access control class"), |
| 123 | EF_TRANSP_N(0x6F7B, "EF.FPLMN", 0, |
| 124 | "Forbidden PLMNs"), |
| 125 | EF_TRANSP_N(0x6F7E, "EF.LOCI", 0, |
| 126 | "Location information"), |
| 127 | EF_TRANSP_N(0x6FAD, "EF.AD", 0, |
| 128 | "Administrative data"), |
| 129 | EF_TRANSP_N(0x6F48, "EF.CBMID", F_OPTIONAL, |
| 130 | "Cell Broadcast Message Identifier for Data Download"), |
| 131 | EF_TRANSP_N(0x6FB7, "EF.ECC", F_OPTIONAL, |
| 132 | "Emergency Call Code"), |
| 133 | EF_TRANSP_N(0x6F50, "EF.CBMIR", F_OPTIONAL, |
| 134 | "Cell broadcast message identifier range selection"), |
| 135 | EF_TRANSP_N(0x6F73, "EF.PSLOCI", 0, |
| 136 | "Pacet Switched location information"), |
| 137 | EF_LIN_FIX_N(0x6F3B, "EF.FDN", F_OPTIONAL, |
| 138 | "Fixed dialling numbers"), |
| 139 | EF_LIN_FIX_N(0x6F3C, "EF.SMS", F_OPTIONAL, |
| 140 | "Short messages"), |
| 141 | EF_LIN_FIX_N(0x6F40, "EF.MSISDN", F_OPTIONAL, |
| 142 | "MSISDN"), |
| 143 | EF_LIN_FIX_N(0x6F42, "EF.SMSP", F_OPTIONAL, |
| 144 | "Short message service parameters"), |
| 145 | EF_TRANSP_N(0x6F43, "EF.SMSS", F_OPTIONAL, |
| 146 | "SMS Status"), |
| 147 | EF_LIN_FIX_N(0x6F49, "EF.SDN", F_OPTIONAL, |
| 148 | "Service Dialling Numbers"), |
| 149 | EF_LIN_FIX_N(0x6F4B, "EF.EXT2", F_OPTIONAL, |
| 150 | "Extension 2"), |
| 151 | EF_LIN_FIX_N(0x6F4C, "EF.EXT3", F_OPTIONAL, |
| 152 | "Extension 3"), |
| 153 | EF_LIN_FIX_N(0x6F47, "EF.SMSR", F_OPTIONAL, |
| 154 | "Short message status reports"), |
| 155 | EF_CYCLIC_N(0x6F80, "EF.ICI", F_OPTIONAL, |
| 156 | "Incoming Calling Information"), |
| 157 | EF_CYCLIC_N(0x6F81, "EF.OCI", F_OPTIONAL, |
| 158 | "Outgoing Calling Information"), |
| 159 | EF_CYCLIC_N(0x6F82, "EF.ICT", F_OPTIONAL, |
| 160 | "Incoming Call Timer"), |
| 161 | EF_CYCLIC_N(0x6F83, "EF.OCT", F_OPTIONAL, |
| 162 | "Outgoing Call Timer"), |
| 163 | EF_LIN_FIX_N(0x6F4E, "EF.EXT5", F_OPTIONAL, |
| 164 | "Extension 5"), |
| 165 | EF_LIN_FIX_N(0x6F4F, "EF.CCP2", F_OPTIONAL, |
| 166 | "Capability Configuration Parameters 2"), |
| 167 | EF_TRANSP_N(0x6FB5, "EF.eMLPP", F_OPTIONAL, |
| 168 | "enhanced Multi Level Precedence and Pre-emption"), |
| 169 | EF_TRANSP_N(0x6FB6, "EF.AAeM", F_OPTIONAL, |
| 170 | "Automatic Answer for eMLPP Service"), |
| 171 | EF_TRANSP_N(0x6FC3, "EF.Hiddenkey", F_OPTIONAL, |
| 172 | "Key for hidden phone book entries"), |
| 173 | EF_LIN_FIX_N(0x6F4D, "EF.BDN", F_OPTIONAL, |
| 174 | "Barred Dialling Numbers"), |
| 175 | EF_LIN_FIX_N(0x6F4E, "EF.EXT4", F_OPTIONAL, |
| 176 | "Extension 4"), |
| 177 | EF_LIN_FIX_N(0x6F58, "EF.CMI", F_OPTIONAL, |
| 178 | "Comparison Method Information"), |
| 179 | EF_TRANSP_N(0x6F56, "EF.EST", F_OPTIONAL, |
| 180 | "Enhanced Services Table"), |
| 181 | EF_TRANSP_N(0x6F57, "EF.ACL", F_OPTIONAL, |
| 182 | "Access Point Name Control List"), |
| 183 | EF_TRANSP_N(0x6F2C, "EF.DCK", F_OPTIONAL, |
| 184 | "Depersonalisation Control Keys"), |
| 185 | EF_TRANSP_N(0x6F32, "EF.CNL", F_OPTIONAL, |
| 186 | "Co-operative Network List"), |
| 187 | EF_TRANSP_N(0x6F5B, "EF.START-HFN", 0, |
| 188 | "Initialisation values for Hyperframe number"), |
| 189 | EF_TRANSP_N(0x6F5C, "EF.THRESHOLD", 0, |
| 190 | "Maximum value of START"), |
| 191 | EF_TRANSP_N(0x6F61, "EF.OPLMNwAcT", F_OPTIONAL, |
| 192 | "Operator controlled PLMN Selector with Access Technology"), |
| 193 | EF_TRANSP_N(0x6F62, "EF.HPLMNwAcT", F_OPTIONAL, |
| 194 | "HPLMN Selector with Access Technology"), |
| 195 | EF_LIN_FIX_N(0x6F06, "EF.ARR", 0, |
| 196 | "Access Rule Reference"), |
| 197 | EF_TRANSP_N(0x6FC4, "EF.NETPAR", 0, |
| 198 | "Network Parameters"), |
| 199 | EF_LIN_FIX_N(0x6FC5, "EF.PNN", F_OPTIONAL, |
| 200 | "PLMN Network Name"), |
| 201 | EF_LIN_FIX_N(0x6FC6, "EF.OPL", F_OPTIONAL, |
| 202 | "Operator PLMN List"), |
| 203 | EF_LIN_FIX_N(0x6FC7, "EF.MBDN", F_OPTIONAL, |
| 204 | "Mailbox Dialling Numbers"), |
| 205 | EF_LIN_FIX_N(0x6FC8, "EF.EXT6", F_OPTIONAL, |
| 206 | "Extension 6"), |
| 207 | EF_LIN_FIX_N(0x6FC9, "EF.MBI", F_OPTIONAL, |
| 208 | "Mailbox Identifier"), |
| 209 | EF_LIN_FIX_N(0x6FCA, "EF.MWIS", F_OPTIONAL, |
| 210 | "Message Waiting Indication Status"), |
| 211 | EF_LIN_FIX_N(0x6FCB, "EF.CFIS", F_OPTIONAL, |
| 212 | "Call Forwarding Indication Status"), |
| 213 | EF_LIN_FIX_N(0x6FCC, "EF.EXT7", F_OPTIONAL, |
| 214 | "Extension 7"), |
| 215 | EF_TRANSP_N(0x6FCD, "EF.SPDI", F_OPTIONAL, |
| 216 | "Service Provider Display Information"), |
| 217 | EF_LIN_FIX_N(0x6FCE, "EF.MMSN", F_OPTIONAL, |
| 218 | "MMS Notification"), |
| 219 | EF_LIN_FIX_N(0x6FCF, "EF.EXT8", F_OPTIONAL, |
| 220 | "Extension 8"), |
| 221 | EF_TRANSP_N(0x6FD0, "EF.MMSICP", F_OPTIONAL, |
| 222 | "MMS Issuer Connectivity Parameters"), |
| 223 | EF_LIN_FIX_N(0x6FD1, "EF.MMSUP", F_OPTIONAL, |
| 224 | "MMS User Preferences"), |
| 225 | EF_TRANSP_N(0x6FD2, "EF.MMSUCP", F_OPTIONAL, |
| 226 | "MMS User Connectivity Parameters"), |
| 227 | EF_LIN_FIX_N(0x6FD3, "EF.NIA", F_OPTIONAL, |
| 228 | "Network's Indication of Alerting"), |
| 229 | EF_TRANSP_N(0x6FB1, "EF.VGCS", F_OPTIONAL, |
| 230 | "Voice Group Call Service"), |
| 231 | EF_TRANSP_N(0x6FB2, "EF.VGCSS", F_OPTIONAL, |
| 232 | "Voice Group Call Service Status"), |
| 233 | EF_TRANSP_N(0x6FB3, "EF.VBS", F_OPTIONAL, |
| 234 | "Voice Broadcast Service"), |
| 235 | EF_TRANSP_N(0x6FB4, "EF.VBSS", F_OPTIONAL, |
| 236 | "Voice Broadcast Service Status"), |
| 237 | EF_TRANSP_N(0x6FD4, "EF.VGCSCA", F_OPTIONAL, |
| 238 | "Voice Group Call Service Ciphering Algorithm"), |
| 239 | EF_TRANSP_N(0x6FD5, "EF.VBSCA", F_OPTIONAL, |
| 240 | "Voice Broadcast Service Ciphering Algorithm"), |
| 241 | EF_TRANSP_N(0x6FD6, "EF.GBABP", F_OPTIONAL, |
| 242 | "GBA Bootstrapping parameters"), |
| 243 | EF_LIN_FIX_N(0x6FD7, "EF.MSK", F_OPTIONAL, |
| 244 | "MBMS Serviec Key List"), |
| 245 | EF_LIN_FIX_N(0x6FD8, "EF.MUK", F_OPTIONAL, |
| 246 | "MBMS User Key"), |
| 247 | EF_LIN_FIX_N(0x6FDA, "EF.GBANL", F_OPTIONAL, |
| 248 | "GBA NAF List"), |
| 249 | EF_TRANSP_N(0x6FD9, "EF.EHPLMN", F_OPTIONAL, |
| 250 | "Equivalent HPLMN"), |
| 251 | }; |
| 252 | |
| 253 | |
| 254 | |
| 255 | /* 31.102 Chapter 4.4.1 */ |
| 256 | static const struct osim_file_desc usim_ef_in_solsa[] = { |
| 257 | EF_TRANSP_N(0x4F30, "EF.SAI", F_OPTIONAL, |
| 258 | "SoLSA Access Indicator"), |
| 259 | EF_LIN_FIX_N(0x4F31, "EF.SLL", F_OPTIONAL, |
| 260 | "SoLSA LSA List"), |
| 261 | /* LSA descriptor files 4Fxx, hard to represent here */ |
| 262 | }; |
| 263 | |
| 264 | /* Annex E - TS 101 220 */ |
| 265 | static const uint8_t adf_usim_aid[] = { 0xA0, 0x00, 0x00, 0x00, 0x87, 0x10, 0x02 }; |
| 266 | |
| 267 | struct osim_card_profile *osim_cprof_usim(void *ctx) |
| 268 | { |
| 269 | struct osim_card_profile *cprof; |
| 270 | struct osim_file_desc *mf, *gsm, *tc, *uadf; |
| 271 | |
| 272 | cprof = talloc_zero(ctx, struct osim_card_profile); |
| 273 | cprof->name = "3GPP USIM"; |
| 274 | cprof->sws = usim_card_sws; |
| 275 | |
| 276 | mf = alloc_df(cprof, 0x3f00, "MF"); |
| 277 | |
| 278 | cprof->mf = mf; |
| 279 | |
| 280 | /* Core UICC Files */ |
| 281 | add_filedesc(mf, uicc_ef_in_mf, ARRAY_SIZE(uicc_ef_in_mf)); |
| 282 | |
| 283 | /* ADF.USIM with its EF siblings */ |
| 284 | uadf = add_adf_with_ef(mf, adf_usim_aid, sizeof(adf_usim_aid), |
| 285 | "ADF.USIM", usim_ef_in_adf_usim, |
| 286 | ARRAY_SIZE(usim_ef_in_adf_usim)); |
| 287 | |
| 288 | /* DFs under ADF.USIM */ |
| 289 | add_df_with_ef(uadf, 0x5F3A, "DF.PHONEBOOK", NULL, 0); |
| 290 | add_df_with_ef(uadf, 0x5F3B, "DF.GSM-ACCESS", usim_ef_in_df_gsm_access, |
| 291 | ARRAY_SIZE(usim_ef_in_df_gsm_access)); |
| 292 | add_df_with_ef(uadf, 0x5F3C, "DF.MExE", NULL, 0); |
| 293 | add_df_with_ef(uadf, 0x5F40, "DF.WLAN", NULL, 0); |
| 294 | add_df_with_ef(uadf, 0x5F70, "DF.SoLSA", usim_ef_in_solsa, ARRAY_SIZE(usim_ef_in_solsa)); |
| 295 | |
| 296 | #if 0 |
| 297 | /* DF.TELECOM as sub-directory of MF */ |
| 298 | tc = add_df_with_ef(mf, 0x7F10, "DF.TELECOM", sim_ef_in_telecom, |
| 299 | ARRAY_SIZE(sim_ef_in_telecom)); |
| 300 | add_df_with_ef(tc, 0x5F50, "DF.GRAPHICS", sim_ef_in_graphics, |
| 301 | ARRAY_SIZE(sim_ef_in_graphics)); |
| 302 | |
| 303 | /* DF.GSM for backwards compatibility */ |
| 304 | gsm = add_df_with_ef(mf, 0x7F20, "DF.GSM", sim_ef_in_gsm, |
| 305 | ARRAY_SIZE(sim_ef_in_gsm)); |
| 306 | /* FIXME: DF's below DF.GSM (51.011) */ |
| 307 | #endif |
| 308 | |
| 309 | return cprof; |
| 310 | } |