FreeCalypso > hg > freecalypso-citrine
comparison comlib/cl_imei.c @ 0:75a11d740a02
initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 09 Jun 2016 00:02:41 +0000 |
parents | |
children | c0f2d21307d1 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:75a11d740a02 |
---|---|
1 /* | |
2 +----------------------------------------------------------------------------- | |
3 | Project : COMLIB | |
4 | Modul : cl_imei.c | |
5 +----------------------------------------------------------------------------- | |
6 | Copyright 2002 Texas Instruments Berlin, AG | |
7 | All rights reserved. | |
8 | | |
9 | This file is confidential and a trade secret of Texas | |
10 | Instruments Berlin, AG | |
11 | The receipt of or possession of this file does not convey | |
12 | any rights to reproduce or disclose its contents or to | |
13 | manufacture, use, or sell anything it may describe, in | |
14 | whole, or in part, without the specific written consent of | |
15 | Texas Instruments Berlin, AG. | |
16 +----------------------------------------------------------------------------- | |
17 | Purpose : Definitions of common library functions: IMEI decryption with | |
18 DES algorithm | |
19 +----------------------------------------------------------------------------- | |
20 */ | |
21 /* | |
22 * Version 1.0 | |
23 */ | |
24 | |
25 /**********************************************************************************/ | |
26 | |
27 /* | |
28 NOTE: | |
29 */ | |
30 | |
31 /**********************************************************************************/ | |
32 | |
33 #ifndef CL_IMEI_C | |
34 #define CL_IMEI_C | |
35 | |
36 #include "config.h" | |
37 #include "fixedconf.h" | |
38 | |
39 #include "typedefs.h" | |
40 #include "vsi.h" /* to get a lot of macros */ | |
41 | |
42 #include "../services/ffs/ffs.h" | |
43 #include "../bsp/mem.h" | |
44 #include "pcm.h" | |
45 | |
46 #include "cl_imei.h" | |
47 #include "cl_des.h" | |
48 #include <string.h> | |
49 | |
50 static UBYTE stored_imei[CL_IMEI_SIZE]; /* when the imei is read once, the value | |
51 is stored in this buffer */ | |
52 static UBYTE imei_flag = 0; /* this flag indicates, if IMEI was successful read | |
53 and is stored in the stored_imei buffer */ | |
54 | |
55 /* Default IMEISV for D-Sample 00440000-350-111-20 */ | |
56 const UBYTE C_DEFAULT_IMEISV_DSAMPLE[CL_IMEI_SIZE] = | |
57 {0x00, 0x44, 0x00, 0x00, 0x35, 0x01, 0x11, 0x20}; | |
58 #define CL_IMEI_FFS_PATH "/etc/IMEISV" | |
59 | |
60 /*==== FUNCTIONS ==================================================*/ | |
61 | |
62 #if CONFIG_TARGET_PIRELLI | |
63 /* | |
64 +------------------------------------------------------------------------------ | |
65 | Function : get_dieID | |
66 +------------------------------------------------------------------------------ | |
67 | Description : the function reads the Die-ID from base band processor and | |
68 | extracts it from 4 BYTEs to 8 BYTEs. | |
69 | | |
70 | Parameters : inBufSize - size of buffer where to store Die ID, min.8 BYTE | |
71 | *outBufPtr - pointer to buffer where to store the Die ID | |
72 | Return : void | |
73 +------------------------------------------------------------------------------ | |
74 */ | |
75 LOCAL void get_dieID(USHORT inBufSize, UBYTE *outBufPtr) | |
76 { | |
77 int i; | |
78 USHORT *outBuf16 = (USHORT*)&outBufPtr[0]; | |
79 volatile USHORT *reg_p = (USHORT *) CL_IMEI_DIE_ID_REG; | |
80 | |
81 TRACE_FUNCTION("get_dieID()"); | |
82 | |
83 if(inBufSize < CL_IMEI_DIE_ID_SIZE){ | |
84 TRACE_ERROR("CL IMEI ERROR: buffer size for Die ID to short!"); | |
85 } | |
86 #ifdef IMEI_DEBUG | |
87 TRACE_EVENT_P1("CL IMEI INFO: Die-ID address(0x%x)", CL_IMEI_DIE_ID_REG); | |
88 #endif | |
89 for (i = 0; i < CL_IMEI_DIE_ID_SIZE; i++) { | |
90 /* Die ID is 4 BYTE long, extract it to 8 BYTE. */ | |
91 outBuf16[i] = (USHORT)(*(UINT8*)(reg_p)++); | |
92 } | |
93 } | |
94 | |
95 extern int pirelli_read_factory_record(uint32 offset, void *userbuf, | |
96 T_FFS_SIZE size, int has_chksum); | |
97 | |
98 #define PIRELLI_IMEI_OFFSET 0x504 | |
99 | |
100 /* | |
101 +------------------------------------------------------------------------------ | |
102 | Function : pirelli_get_imeisv | |
103 +------------------------------------------------------------------------------ | |
104 | Description : This function attempts to read and decrypt a valid IMEISV | |
105 | record from Pirelli's factory data block. | |
106 | | |
107 | Parameters : inBufSize - size of buffer where to store IMEI, min. 8 BYTE | |
108 | *outBufPtr - pointer to buffer where to store the IMEI | |
109 | Return : 0 - OK | |
110 | <0 - ERROR | |
111 +------------------------------------------------------------------------------ | |
112 */ | |
113 LOCAL BYTE pirelli_get_imeisv (USHORT inBufSize, UBYTE *outBufPtr) | |
114 { | |
115 UBYTE isdid_buf[CL_IMEI_ISDID_SIZE]; | |
116 UBYTE r_dieId[CL_DES_KEY_SIZE]; /* read Die ID */ | |
117 UBYTE d_dieId[CL_DES_KEY_SIZE]; /* deciphered Die ID */ | |
118 SHORT ret; | |
119 | |
120 TRACE_FUNCTION("pirelli_get_imeisv()"); | |
121 | |
122 if(inBufSize < CL_IMEI_SIZE){ | |
123 TRACE_ERROR("CL IMEI ERROR: buffer size for IMEI to short!"); | |
124 return CL_IMEI_ERROR; | |
125 } | |
126 | |
127 /* | |
128 * Read ISDID(enciphered IMEISV+DieID) from FFS. | |
129 * (changed to read from Pirelli's factory data block instead) | |
130 */ | |
131 if((ret = pirelli_read_factory_record(PIRELLI_IMEI_OFFSET, isdid_buf, | |
132 CL_IMEI_ISDID_SIZE, 0)) >= EFFS_OK) | |
133 { | |
134 /* | |
135 * Read Die ID for using as DES key | |
136 */ | |
137 get_dieID(CL_DES_KEY_SIZE, r_dieId); | |
138 /* | |
139 * Call DES algorithm routine | |
140 */ | |
141 /* decipher first 8 BYTEs */ | |
142 cl_des(&isdid_buf[0], r_dieId, outBufPtr, CL_DES_DECRYPTION); | |
143 /* decipher the rest 8 BYTEs */ | |
144 cl_des(&isdid_buf[CL_DES_BUFFER_SIZE], r_dieId, d_dieId, CL_DES_DECRYPTION); | |
145 if(!memcmp(d_dieId, r_dieId, CL_DES_KEY_SIZE)) | |
146 { | |
147 /* Die ID is valid */ | |
148 ret = CL_IMEI_OK; | |
149 } else {/* Die ID is corrupted */ | |
150 char pr_buf[126]; | |
151 TRACE_ERROR("CL IMEI ERROR: Die ID is corrupted"); | |
152 sprintf(pr_buf,"Read DieID: %02x %02x %02x %02x %02x %02x %02x %02x", | |
153 r_dieId[0], r_dieId[1], r_dieId[2], r_dieId[3], | |
154 r_dieId[4], r_dieId[5], r_dieId[6], r_dieId[7]); | |
155 TRACE_ERROR(pr_buf); | |
156 sprintf(pr_buf,"Deciphered DieID: %02x %02x %02x %02x %02x %02x %02x %02x", | |
157 d_dieId[0], d_dieId[1], d_dieId[2], d_dieId[3], | |
158 d_dieId[4], d_dieId[5], d_dieId[6], d_dieId[7]); | |
159 TRACE_ERROR(pr_buf); | |
160 | |
161 ret = CL_IMEI_INVALID_DIE_ID; | |
162 } | |
163 } else { | |
164 ret = CL_IMEI_READ_IMEI_FAILED; | |
165 } | |
166 | |
167 return ret; | |
168 | |
169 }/* pirelli_get_imeisv() */ | |
170 #endif /* CONFIG_TARGET_PIRELLI */ | |
171 | |
172 | |
173 /* | |
174 +------------------------------------------------------------------------------ | |
175 | Function : cl_get_imeisv | |
176 +------------------------------------------------------------------------------ | |
177 | Description : Common IMEI getter function | |
178 | | |
179 | Parameters : imeiBufSize - size of buffer where to store IMEI, min 8 BYTEs | |
180 | *imeiBufPtr - pointer to buffer where to store the IMEI | |
181 | imeiType - indicates, if the IMEI should be read from | |
182 | FFS/Secure ROM (value=CL_IMEI_GET_SECURE_IMEI) or | |
183 | if the already read and stored IMEI (if available) | |
184 | should be delivered (value=CL_IMEI_GET_STORED_IMEI) | |
185 | The second option should be used only by ACI or | |
186 | BMI to show the IMEISV on mobile's display or | |
187 | in terminal window, e.g. if user calls *#06#. | |
188 | For IMEI Control reason (used by ACI), the value | |
189 | has to be CL_IMEI_CONTROL_IMEI | |
190 | Return : OK - 0 | |
191 | ERROR - negative values | |
192 +------------------------------------------------------------------------------ | |
193 */ | |
194 extern BYTE cl_get_imeisv(USHORT imeiBufSize, UBYTE *imeiBufPtr, UBYTE imeiType) | |
195 { | |
196 #if CONFIG_MOKOFFS | |
197 USHORT ret; | |
198 UBYTE version; | |
199 UBYTE buf[SIZE_EF_IMEI]; | |
200 #else | |
201 BYTE ret; | |
202 #endif | |
203 | |
204 TRACE_FUNCTION("cl_get_imeisv()"); | |
205 | |
206 /* | |
207 * The user has required a stored IMEI. If it has been already read | |
208 * and stored, so return stored IMEI | |
209 */ | |
210 if((imeiType == CL_IMEI_GET_STORED_IMEI) && (imei_flag == 1)){ | |
211 memcpy(imeiBufPtr, stored_imei, CL_IMEI_SIZE); | |
212 return CL_IMEI_OK; | |
213 } | |
214 /* | |
215 * The user has required a "secure" IMEI. How we get it depends on what | |
216 * platform we are running on. | |
217 */ | |
218 | |
219 #if CONFIG_MOKOFFS | |
220 /* | |
221 * Running on Openmoko GTA0x and using the original FFS. | |
222 * Get the nibble-swapped IMEI record from PCM. | |
223 */ | |
224 ret = pcm_ReadFile ((UBYTE *)EF_IMEI_ID, SIZE_EF_IMEI, buf, &version); | |
225 if(ret == PCM_OK){ | |
226 TRACE_EVENT("CL IMEI INFO: return IMEI-SV number from ffs:/pcm/IMEI"); | |
227 /* | |
228 * swap digits | |
229 */ | |
230 imeiBufPtr[0] = ((buf[0] & 0xf0) >> 4) | ((buf[0] & 0x0f) << 4); | |
231 imeiBufPtr[1] = ((buf[1] & 0xf0) >> 4) | ((buf[1] & 0x0f) << 4); | |
232 imeiBufPtr[2] = ((buf[2] & 0xf0) >> 4) | ((buf[2] & 0x0f) << 4); | |
233 imeiBufPtr[3] = ((buf[3] & 0xf0) >> 4) | ((buf[3] & 0x0f) << 4); | |
234 imeiBufPtr[4] = ((buf[4] & 0xf0) >> 4) | ((buf[4] & 0x0f) << 4); | |
235 imeiBufPtr[5] = ((buf[5] & 0xf0) >> 4) | ((buf[5] & 0x0f) << 4); | |
236 imeiBufPtr[6] = ((buf[6] & 0xf0) >> 4) | ((buf[6] & 0x0f) << 4); | |
237 imeiBufPtr[7] = ((buf[7] & 0xf0) >> 4) | ((buf[7] & 0x0f) << 4); | |
238 /* store IMEI */ | |
239 memcpy(stored_imei, imeiBufPtr, CL_IMEI_SIZE); | |
240 imei_flag = 1; | |
241 }else{ | |
242 /* | |
243 * pcm_ReadFile() can't really fail, as it merely reads out of a | |
244 * RAM buffer that was filled earlier, either from FFS or from | |
245 * compiled-in defaults. But TI's original code had the following | |
246 * error handling clause, so I kept it. | |
247 */ | |
248 TRACE_EVENT("CL IMEI INFO: return default IMEI-SV number"); | |
249 memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE); | |
250 } | |
251 return CL_IMEI_OK; | |
252 #else | |
253 | |
254 /* | |
255 * Regular FreeCalypso configuration, not MokoFFS. | |
256 * We try to get the IMEISV from the following sources, in this order: | |
257 * | |
258 * /etc/IMEISV (sensible nibble order, not encrypted) | |
259 * Pirelli's encrypted IMEI record (Pirelli target only) | |
260 * hard-coded fallback and error indication | |
261 */ | |
262 | |
263 if (ffs_file_read(CL_IMEI_FFS_PATH, imeiBufPtr, CL_IMEI_SIZE) >= EFFS_OK) { | |
264 memcpy(stored_imei, imeiBufPtr, CL_IMEI_SIZE); | |
265 imei_flag = 1; | |
266 return CL_IMEI_OK; | |
267 } | |
268 #if CONFIG_TARGET_PIRELLI | |
269 ret = pirelli_get_imeisv (imeiBufSize, imeiBufPtr); | |
270 if (ret == CL_IMEI_OK) { | |
271 imei_flag = 1; | |
272 return ret; | |
273 } | |
274 #else | |
275 ret = CL_IMEI_READ_IMEI_FAILED; | |
276 #endif | |
277 TRACE_ERROR("CL IMEI FATAL ERROR: IMEI not available!"); | |
278 memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE); | |
279 return ret; | |
280 #endif /* CONFIG_MOKOFFS */ | |
281 } | |
282 | |
283 #endif /* CL_IMEI_C */ |