summaryrefslogtreecommitdiffstats
path: root/src/host/layer23/include/osmocom/bb/common/sim.h
blob: 8b1f830ce15802eebdca91013c3853ae14c88fa9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
/*
 * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
 *
 * 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.
 *
 */


/* 9.2 commands */
#define GSM1111_CLASS_GSM		0xa0
#define	GSM1111_INST_SELECT		0xa4
#define	GSM1111_INST_STATUS		0xf2
#define	GSM1111_INST_READ_BINARY	0xb0
#define	GSM1111_INST_UPDATE_BINARY	0xd6
#define	GSM1111_INST_READ_RECORD	0xb2
#define	GSM1111_INST_UPDATE_RECORD	0xdc
#define	GSM1111_INST_SEEK		0xa2
#define	GSM1111_INST_INCREASE		0x32
#define	GSM1111_INST_VERIFY_CHV		0x20
#define	GSM1111_INST_CHANGE_CHV		0x24
#define	GSM1111_INST_DISABLE_CHV	0x26
#define	GSM1111_INST_ENABLE_CHV		0x28
#define	GSM1111_INST_UNBLOCK_CHV	0x2c
#define	GSM1111_INST_INVALIDATE		0x04
#define	GSM1111_INST_REHABLILITATE	0x44
#define	GSM1111_INST_RUN_GSM_ALGO	0x88
#define	GSM1111_INST_SLEEP		0xfa
#define	GSM1111_INST_GET_RESPONSE	0xc0
#define	GSM1111_INST_TERMINAL_PROFILE	0x10
#define	GSM1111_INST_ENVELOPE		0xc2
#define	GSM1111_INST_FETCH		0x12
#define	GSM1111_INST_TERMINAL_RESPONSE	0x14

/* 9.3 access conditions */
#define GSM1111_ACC_ALWAYS		0x0
#define GSM1111_ACC_CHV1		0x1
#define GSM1111_ACC_CHV2		0x2
#define GSM1111_ACC_RFU			0x3
#define GSM1111_ACC_NEW			0xf
/* others are ADM */

/* 9.3 type of file */
#define GSM1111_TOF_RFU			0x00
#define GSM1111_TOF_MF			0x01
#define GSM1111_TOF_DF			0x02
#define GSM1111_TOF_EF			0x04

/* 9.3 struct of file */
#define GSM1111_SOF_TRANSPARENT		0x00
#define GSM1111_SOF_LINEAR		0x01
#define GSM1111_SOF_CYCLIC		0x03

/* 9.4 status */
#define GSM1111_STAT_NORMAL		0x90
#define GSM1111_STAT_PROACTIVE		0x91
#define GSM1111_STAT_DL_ERROR		0x9e
#define GSM1111_STAT_RESPONSE		0x9f
#define GSM1111_STAT_RESPONSE_TOO	0x61
#define GSM1111_STAT_APP_TK_BUSY	0x93
#define GSM1111_STAT_MEM_PROBLEM	0x92
#define GSM1111_STAT_REFERENCING	0x94
#define GSM1111_STAT_SECURITY		0x98
#define GSM1111_STAT_INCORR_P3		0x67
#define GSM1111_STAT_INCORR_P1_P2	0x6b
#define GSM1111_STAT_UKN_INST		0x6d
#define GSM1111_STAT_WRONG_CLASS	0x6e
#define GSM1111_STAT_TECH_PROBLEM	0x6f

/* 9.4.4 Referencing management SW2 */
#define GSM1111_REF_NO_EF		0x00
#define GSM1111_REF_OUT_OF_RANGE	0x02
#define GSM1111_REF_FILE_NOT_FOUND	0x04
#define GSM1111_REF_FILE_INCONSI	0x08

/* 9.4.5 Security management SW2 */
#define GSM1111_SEC_NO_CHV		0x02
#define GSM1111_SEC_NO_ACCESS		0x04
#define GSM1111_SEC_CONTRA_CHV		0x08
#define GSM1111_SEC_CONTRA_INVAL	0x10
#define GSM1111_SEC_BLOCKED		0x40
#define GSM1111_SEC_MAX_VALUE		0x50

/* messages from application to sim client */
enum {
	/* requests */
	SIM_JOB_READ_BINARY,
	SIM_JOB_UPDATE_BINARY,
	SIM_JOB_READ_RECORD,
	SIM_JOB_UPDATE_RECORD,
	SIM_JOB_SEEK_RECORD,
	SIM_JOB_INCREASE,
	SIM_JOB_INVALIDATE,
	SIM_JOB_REHABILITATE,
	SIM_JOB_RUN_GSM_ALGO,
	SIM_JOB_PIN1_UNLOCK,
	SIM_JOB_PIN1_CHANGE,
	SIM_JOB_PIN1_DISABLE,
	SIM_JOB_PIN1_ENABLE,
	SIM_JOB_PIN1_UNBLOCK,
	SIM_JOB_PIN2_UNLOCK,
	SIM_JOB_PIN2_CHANGE,
	SIM_JOB_PIN2_UNBLOCK,

	/* results */
	SIM_JOB_OK,
	SIM_JOB_ERROR,
};

/* messages from sim client to application */
#define SIM_JOB_OK		0
#define SIM_JOB_ERROR		1

/* error causes */
#define SIM_CAUSE_NO_SIM	0	/* no SIM present, if detectable */
#define SIM_CAUSE_SIM_ERROR	1	/* any error while reading SIM */
#define SIM_CAUSE_REQUEST_ERROR	2	/* error in request */
#define SIM_CAUSE_PIN1_REQUIRED	3	/* CHV1 is required for access */
#define SIM_CAUSE_PIN2_REQUIRED	4	/* CHV2 is required for access */
#define SIM_CAUSE_PIN1_BLOCKED	5	/* CHV1 was entered too many times */
#define SIM_CAUSE_PIN2_BLOCKED	6	/* CHV2 was entered too many times */
#define SIM_CAUSE_PUC_BLOCKED	7	/* unblock entered too many times */

/* job states */
enum {
	SIM_JST_IDLE = 0,
	SIM_JST_SELECT_MFDF,		/* SELECT sent */
	SIM_JST_SELECT_MFDF_RESP,	/* GET RESPONSE sent */
	SIM_JST_SELECT_EF,		/* SELECT sent */
	SIM_JST_SELECT_EF_RESP,		/* GET RESPONSE sent */
	SIM_JST_WAIT_FILE,		/* file command sent */
	SIM_JST_RUN_GSM_ALGO,		/* wait for algorithm to process */
	SIM_JST_RUN_GSM_ALGO_RESP,	/* wait for response */
	SIM_JST_PIN1_UNLOCK,
	SIM_JST_PIN1_CHANGE,
	SIM_JST_PIN1_DISABLE,
	SIM_JST_PIN1_ENABLE,
	SIM_JST_PIN1_UNBLOCK,
	SIM_JST_PIN2_UNLOCK,
	SIM_JST_PIN2_CHANGE,
	SIM_JST_PIN2_UNBLOCK,
};

#define MAX_SIM_PATH_LENGTH	6 + 1 /* one for the termination */

struct gsm_sim_handler {
	struct llist_head	entry;

	uint32_t		handle;
	void			(*cb)(struct osmocom_ms *ms, struct msgb *msg);
};

struct gsm_sim {
	struct llist_head	handlers; /* gsm_sim_handler */
	struct llist_head	jobs; /* messages */
	uint16_t path[MAX_SIM_PATH_LENGTH];
	uint16_t file;

	struct msgb		*job_msg;
	uint32_t		job_handle;
	int			job_state;

	uint8_t			reset;
	uint8_t			chv1_remain, chv2_remain;
	uint8_t			unblk1_remain, unblk2_remain;

	/* APDU cache (used by GSMTAP) */
	uint8_t apdu_data[256 + 7];
	uint16_t apdu_len;
};

struct sim_hdr {
	int handle;
	uint8_t job_type;
	uint16_t path[MAX_SIM_PATH_LENGTH];
	uint16_t file;
	uint8_t rec_no, rec_mode; /* in case of record */
	uint8_t seek_type_mode; /* in case of seek command */
};

#define SIM_ALLOC_SIZE		512
#define SIM_ALLOC_HEADROOM	64

struct msgb *gsm_sim_msgb_alloc(uint32_t handle, uint8_t job_type);
uint32_t sim_open(struct osmocom_ms *ms,
	void (*cb)(struct osmocom_ms *ms, struct msgb *msg));
void sim_close(struct osmocom_ms *ms, uint32_t handle);
void sim_job(struct osmocom_ms *ms, struct msgb *msg);

/* Section 9.2.1 (response to selecting DF or MF) */
struct gsm1111_response_mfdf {
	uint16_t rfu1;
	uint16_t free_mem;
	uint16_t file_id;
	uint8_t tof;
	uint8_t	rfu2[5];
	uint8_t length;
	uint8_t gsm_data[0];
} __attribute__ ((packed));

struct gsm1111_response_mfdf_gsm {
	uint8_t file_char;
	uint8_t num_df;
	uint8_t num_ef;
	uint8_t num_codes;
	uint8_t rfu1;
	uint8_t chv1_remain:4,
		 rfu2:3,
		 chv1_init:1;
	uint8_t unblk1_remain:4,
		 rfu3:3,
		 unblk1_init:1;
	uint8_t chv2_remain:4,
		 rfu4:3,
		 chv2_init:1;
	uint8_t unblk2_remain:4,
		 rfu5:3,
		 unblk2_init:1;
	uint8_t more_data[0];
} __attribute__ ((packed));

/* Section 9.2.1 (response to selecting EF) */
struct gsm1111_response_ef {
	uint16_t rfu1;
	uint16_t file_size;
	uint16_t file_id;
	uint8_t tof;
	uint8_t inc_allowed;
	uint8_t	acc_update:4,
		 acc_read:4;
	uint8_t	rfu2:4,
		 acc_inc:4;
	uint8_t	acc_inval:4,
		 acc_reha:4;
	uint8_t not_inval:1,
		 rfu3:1,
		 ru_inval:1,
		 rfu4:5;
	uint8_t length;
	uint8_t structure;
} __attribute__ ((packed));

/* Section 10.3.17 */
struct gsm1111_ef_loci {
	uint32_t tmsi;
	struct gsm48_loc_area_id lai;
	uint8_t tmsi_time;
	uint8_t lupd_status;
} __attribute__ ((packed));

/* Section 10.5.1 */
struct gsm1111_ef_adn {
	uint8_t len_bcd;
	uint8_t ton_npi;
	uint8_t number[10];
	uint8_t capa_conf;
	uint8_t ext_id;
} __attribute__ ((packed));

/* Section 10.5.6 */
struct gsm1111_ef_smsp {
	uint8_t par_ind;
	uint8_t tp_da[12];
	uint8_t ts_sca[12];
	uint8_t tp_proto;
	uint8_t tp_dcs;
	uint8_t tp_vp;
} __attribute__ ((packed));

int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg);
int gsm_sim_init(struct osmocom_ms *ms);
int gsm_sim_exit(struct osmocom_ms *ms);
int gsm_sim_job_dequeue(struct osmocom_ms *ms);