comparison gsm-fw/comlib/cl_imei.c @ 667:b34e5351438e

cl_imei.[ch]: revamped for FreeCalypso
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 28 Sep 2014 07:27:25 +0000
parents d36f647c2432
children f3fba126778a
comparison
equal deleted inserted replaced
666:8f9389e59ca2 667:b34e5351438e
31 /**********************************************************************************/ 31 /**********************************************************************************/
32 32
33 #ifndef CL_IMEI_C 33 #ifndef CL_IMEI_C
34 #define CL_IMEI_C 34 #define CL_IMEI_C
35 35
36 #include "config.h"
37 #include "fixedconf.h"
38
36 #include "typedefs.h" 39 #include "typedefs.h"
37 #include "vsi.h" /* to get a lot of macros */ 40 #include "vsi.h" /* to get a lot of macros */
38 41
39 #ifndef _SIMULATION_ 42 #include "../services/ffs/ffs.h"
40 #include "ffs/ffs.h" 43 #include "../bsp/mem.h"
41 #include "config/chipset.cfg"
42 #include "config/board.cfg"
43 #include "memif/mem.h"
44 #include "pcm.h" 44 #include "pcm.h"
45 #endif /* ifdef SIMULATION */
46 45
47 #include "cl_imei.h" 46 #include "cl_imei.h"
48 #include "cl_des.h" 47 #include "cl_des.h"
49 #include <string.h> 48 #include <string.h>
50
51 #if defined(CL_IMEI_CALYPSO_PLUS_PLATFORM) && defined(FF_PROTECTED_IMEI)
52 #include "secure_rom/secure_rom.h"
53 #endif
54 49
55 static UBYTE stored_imei[CL_IMEI_SIZE]; /* when the imei is read once, the value 50 static UBYTE stored_imei[CL_IMEI_SIZE]; /* when the imei is read once, the value
56 is stored in this buffer */ 51 is stored in this buffer */
57 static UBYTE imei_flag = 0; /* this flag indicates, if IMEI was successful read 52 static UBYTE imei_flag = 0; /* this flag indicates, if IMEI was successful read
58 and is stored in the stored_imei buffer */ 53 and is stored in the stored_imei buffer */
59 54
60 #if !defined (CL_IMEI_CALYPSO_PLUS_PLATFORM)
61 /* Default IMEISV for D-Sample 00440000-350-111-20 */ 55 /* Default IMEISV for D-Sample 00440000-350-111-20 */
62 const UBYTE C_DEFAULT_IMEISV_DSAMPLE[CL_IMEI_SIZE] = 56 const UBYTE C_DEFAULT_IMEISV_DSAMPLE[CL_IMEI_SIZE] =
63 {0x00, 0x44, 0x00, 0x00, 0x35, 0x01, 0x11, 0x20}; 57 {0x00, 0x44, 0x00, 0x00, 0x35, 0x01, 0x11, 0x20};
64 #define CL_IMEI_FFS_PATH "/gsm/imei.enc" 58 #define CL_IMEI_FFS_PATH "/etc/IMEISV"
65 #endif /* CL_IMEI_CALYPSO_PLATFORM */
66
67 #ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM
68 /* Default IMEISV for E-Sample 00440000-351-222-30 */
69 const UBYTE C_DEFAULT_IMEISV_ESAMPLE[CL_IMEI_SIZE] =
70 {0x00, 0x44, 0x00, 0x00, 0x35, 0x12, 0x22, 0x30};
71 #endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
72 59
73 /*==== FUNCTIONS ==================================================*/ 60 /*==== FUNCTIONS ==================================================*/
74 #ifdef FF_PROTECTED_IMEI 61
75 62 #if CONFIG_TARGET_PIRELLI
76 #ifdef CL_IMEI_CALYPSO_PLATFORM
77 /* 63 /*
78 +------------------------------------------------------------------------------ 64 +------------------------------------------------------------------------------
79 | Function : get_dieID 65 | Function : get_dieID
80 +------------------------------------------------------------------------------ 66 +------------------------------------------------------------------------------
81 | Description : the function reads the Die-ID from base band processor and 67 | Description : the function reads the Die-ID from base band processor and
104 /* Die ID is 4 BYTE long, extract it to 8 BYTE. */ 90 /* Die ID is 4 BYTE long, extract it to 8 BYTE. */
105 outBuf16[i] = (USHORT)(*(UINT8*)(reg_p)++); 91 outBuf16[i] = (USHORT)(*(UINT8*)(reg_p)++);
106 } 92 }
107 } 93 }
108 94
109 /* 95 #if 0 // function for reading from Pirelli's factory block not written yet
110 +------------------------------------------------------------------------------ 96 /*
111 | Function : ffs_get_imeisv 97 +------------------------------------------------------------------------------
112 +------------------------------------------------------------------------------ 98 | Function : pirelli_get_imeisv
113 | Description : the function reads IMEI from FFS 99 +------------------------------------------------------------------------------
100 | Description : This function attempts to read and decrypt a valid IMEISV
101 | record from Pirelli's factory data block.
114 | 102 |
115 | Parameters : inBufSize - size of buffer where to store IMEI, min. 8 BYTE 103 | Parameters : inBufSize - size of buffer where to store IMEI, min. 8 BYTE
116 | *outBufPtr - pointer to buffer where to store the IMEI 104 | *outBufPtr - pointer to buffer where to store the IMEI
117 | Return : 0 - OK 105 | Return : 0 - OK
118 | <0 - ERROR 106 | <0 - ERROR
119 +------------------------------------------------------------------------------ 107 +------------------------------------------------------------------------------
120 */ 108 */
121 LOCAL BYTE ffs_get_imeisv (USHORT inBufSize, UBYTE *outBufPtr) 109 LOCAL BYTE pirelli_get_imeisv (USHORT inBufSize, UBYTE *outBufPtr)
122 { 110 {
123 UBYTE i;
124 UBYTE isdid_buf[CL_IMEI_ISDID_SIZE]; 111 UBYTE isdid_buf[CL_IMEI_ISDID_SIZE];
125 UBYTE r_dieId[CL_DES_KEY_SIZE]; /* read Die ID */ 112 UBYTE r_dieId[CL_DES_KEY_SIZE]; /* read Die ID */
126 UBYTE d_dieId[CL_DES_KEY_SIZE]; /* deciphered Die ID */ 113 UBYTE d_dieId[CL_DES_KEY_SIZE]; /* deciphered Die ID */
127 SHORT ret; 114 SHORT ret;
128 115
129 TRACE_FUNCTION("ffs_get_imeisv()"); 116 TRACE_FUNCTION("pirelli_get_imeisv()");
130 117
131 if(inBufSize < CL_IMEI_SIZE){ 118 if(inBufSize < CL_IMEI_SIZE){
132 TRACE_ERROR("CL IMEI ERROR: buffer size for IMEI to short!"); 119 TRACE_ERROR("CL IMEI ERROR: buffer size for IMEI to short!");
133 return CL_IMEI_ERROR; 120 return CL_IMEI_ERROR;
134 } 121 }
135 122
136 /* 123 /*
137 * Read ISDID(enciphered IMEISV+DieID) from FFS. 124 * Read ISDID(enciphered IMEISV+DieID) from FFS.
125 * TODO: change the code to read from Pirelli's factory data block instead
138 */ 126 */
139 if((ret = ffs_file_read(CL_IMEI_FFS_PATH, isdid_buf, CL_IMEI_ISDID_SIZE)) >= EFFS_OK) 127 if((ret = ffs_file_read(CL_IMEI_FFS_PATH, isdid_buf, CL_IMEI_ISDID_SIZE)) >= EFFS_OK)
140 { 128 {
141 /* 129 /*
142 * Read Die ID for using as DES key 130 * Read Die ID for using as DES key
169 } 157 }
170 } else { 158 } else {
171 ret = CL_IMEI_READ_IMEI_FAILED; 159 ret = CL_IMEI_READ_IMEI_FAILED;
172 } 160 }
173 161
174 return ret; 162 return ret;
175 163
176 }/* ffs_get_imeisv() */ 164 }/* pirelli_get_imeisv() */
177 #endif /* CL_IMEI_CALYPSO_PLATFORM */ 165 #endif /* #if 0 */
178 166 #endif /* CONFIG_TARGET_PIRELLI */
179 167
180 #ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM
181 /*
182 +------------------------------------------------------------------------------
183 | Function : securerom_get_imeisv
184 +------------------------------------------------------------------------------
185 | Description : the function reads IMEI from Secure ROM
186 |
187 | Parameters : inBufSize - size of buffer where to store IMEI, min. 8 BYTE
188 | *outBufPtr - pointer to buffer where to store the IMEI
189 | Return : 0 - OK
190 | <0 - ERROR
191 +------------------------------------------------------------------------------
192 */
193 LOCAL BYTE securerom_get_imeisv (USHORT inBufSize, UBYTE *outBufPtr)
194 {
195 BYTE ret;
196
197 TRACE_FUNCTION("securerom_get_imeisv()");
198
199 if((ret = securerom_drv(inBufSize, outBufPtr)) == CL_IMEI_OK){
200 return CL_IMEI_OK;
201 } else {
202 return CL_IMEI_READ_IMEI_FAILED;
203 }
204 }
205 #endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
206
207 /*
208 +------------------------------------------------------------------------------
209 | Function : get_secure_imeisv
210 +------------------------------------------------------------------------------
211 | Description : the function reads IMEI either from FFS or from Secure ROM of
212 | from other locations depended on hardware platform
213 |
214 | Parameters : inBufSize - size of buffer where to store IMEI, min. 8 BYTE
215 | *outBufPtr - pointer to buffer where to store the IMEI
216 | Return : 0 - OK
217 | negative value - ERROR
218 +------------------------------------------------------------------------------
219 */
220 LOCAL BYTE get_secure_imeisv(USHORT inBufSize, UBYTE *outBufPtr)
221 {
222 BYTE ret = 0;
223 UBYTE chipset = CHIPSET;
224 UBYTE board = BOARD;
225
226 TRACE_FUNCTION("get_secure_imeisv()");
227
228 /*
229 * SW is running on Calypso platform (D-Sample)
230 */
231 #ifdef CL_IMEI_CALYPSO_PLATFORM
232 /*
233 * Read IMEI from FFS inclusive deciphering with DES.
234 */
235 if((ret = ffs_get_imeisv (inBufSize, outBufPtr)) == CL_IMEI_OK)
236 {
237 /* store IMEI */
238 memcpy(stored_imei, outBufPtr, CL_IMEI_SIZE);
239 imei_flag = 1;
240 return CL_IMEI_OK;
241 }
242 #else /* CL_IMEI_CALYPSO_PLATFORM */
243 /*
244 * SW is running on Calypso plus platform (E-Sample)
245 */
246 #ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM
247 if((ret = securerom_get_imeisv (inBufSize, outBufPtr)) == CL_IMEI_OK)
248 {
249 /* store IMEI */
250 memcpy(stored_imei, outBufPtr, CL_IMEI_SIZE);
251 imei_flag = 1;
252 return CL_IMEI_OK;
253 }
254 #else /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
255 /*
256 * SW is running on an other platform (neither Calypso nor Calypso plus)
257 */
258 #ifdef CL_IMEI_OTHER_PLATFORM
259 {
260 TRACE_EVENT_P2("CL IMEI WARNING: unknown hardware: board=%d, chipset=%d, return default imei",
261 board, chipset);
262 memcpy(outBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE);
263 return CL_IMEI_OK;
264 }
265 #endif /* CL_IMEI_OTHER_PLATFORM */
266 #endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
267 #endif /* CL_IMEI_CALYPSO_PLATFORM */
268
269 return ret; /* get_secure_imeisv is failed, return error code */
270
271 } /* get_secure_imeisv() */
272
273
274 #endif /* FF_PROTECTED_IMEI */
275 168
276 /* 169 /*
277 +------------------------------------------------------------------------------ 170 +------------------------------------------------------------------------------
278 | Function : cl_get_imeisv 171 | Function : cl_get_imeisv
279 +------------------------------------------------------------------------------ 172 +------------------------------------------------------------------------------
294 | ERROR - negative values 187 | ERROR - negative values
295 +------------------------------------------------------------------------------ 188 +------------------------------------------------------------------------------
296 */ 189 */
297 extern BYTE cl_get_imeisv(USHORT imeiBufSize, UBYTE *imeiBufPtr, UBYTE imeiType) 190 extern BYTE cl_get_imeisv(USHORT imeiBufSize, UBYTE *imeiBufPtr, UBYTE imeiType)
298 { 191 {
299 BYTE ret = 0; 192 USHORT ret;
193 #if CONFIG_MOKOFFS
194 UBYTE version;
195 UBYTE buf[SIZE_EF_IMEI];
196 #endif
300 197
301 TRACE_FUNCTION("cl_get_imeisv()"); 198 TRACE_FUNCTION("cl_get_imeisv()");
302 199
303 #ifdef _SIMULATION_
304 memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE);
305 return CL_IMEI_OK;
306 #else /* _SIMULATION_ */
307
308 #ifdef FF_PROTECTED_IMEI
309 /* 200 /*
310 * The user has required a stored IMEI. If it has been already read 201 * The user has required a stored IMEI. If it has been already read
311 * and stored, so return stored IMEI 202 * and stored, so return stored IMEI
312 */ 203 */
313 if((imeiType == CL_IMEI_GET_STORED_IMEI) && (imei_flag == 1)){ 204 if((imeiType == CL_IMEI_GET_STORED_IMEI) && (imei_flag == 1)){
314 memcpy(imeiBufPtr, stored_imei, CL_IMEI_SIZE); 205 memcpy(imeiBufPtr, stored_imei, CL_IMEI_SIZE);
315 return CL_IMEI_OK; 206 return CL_IMEI_OK;
316 } 207 }
317 /* 208 /*
318 * The user has required a secure IMEI. Read IMEI from FFS or from Secure ROM 209 * The user has required a "secure" IMEI. How we get it depends on what
319 */ 210 * platform we are running on.
320 if((ret = get_secure_imeisv(imeiBufSize, imeiBufPtr)) == CL_IMEI_OK) 211 */
321 { 212
213 #if CONFIG_MOKOFFS
214 /*
215 * Running on Openmoko GTA0x and using the original FFS.
216 * Get the nibble-swapped IMEI record from PCM.
217 */
218 ret = pcm_ReadFile ((UBYTE *)EF_IMEI_ID, SIZE_EF_IMEI, buf, &version);
219 if(ret == PCM_OK){
220 TRACE_EVENT("CL IMEI INFO: return IMEI-SV number from ffs:/pcm/IMEI");
221 /*
222 * swap digits
223 */
224 imeiBufPtr[0] = ((buf[0] & 0xf0) >> 4) | ((buf[0] & 0x0f) << 4);
225 imeiBufPtr[1] = ((buf[1] & 0xf0) >> 4) | ((buf[1] & 0x0f) << 4);
226 imeiBufPtr[2] = ((buf[2] & 0xf0) >> 4) | ((buf[2] & 0x0f) << 4);
227 imeiBufPtr[3] = ((buf[3] & 0xf0) >> 4) | ((buf[3] & 0x0f) << 4);
228 imeiBufPtr[4] = ((buf[4] & 0xf0) >> 4) | ((buf[4] & 0x0f) << 4);
229 imeiBufPtr[5] = ((buf[5] & 0xf0) >> 4) | ((buf[5] & 0x0f) << 4);
230 imeiBufPtr[6] = ((buf[6] & 0xf0) >> 4) | ((buf[6] & 0x0f) << 4);
231 imeiBufPtr[7] = ((buf[7] & 0xf0) >> 4) | ((buf[7] & 0x0f) << 4);
232 /* store IMEI */
233 memcpy(stored_imei, imeiBufPtr, CL_IMEI_SIZE);
234 imei_flag = 1;
235 }else{
236 /*
237 * pcm_ReadFile() can't really fail, as it merely reads out of a
238 * RAM buffer that was filled earlier, either from FFS or from
239 * compiled-in defaults. But TI's original code had the following
240 * error handling clause, so I kept it.
241 */
242 TRACE_EVENT("CL IMEI INFO: return default IMEI-SV number");
243 memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE);
244 }
245 return CL_IMEI_OK;
246 #else
247
248 /*
249 * Regular FreeCalypso configuration, not MokoFFS.
250 * We try to get the IMEISV from the following sources, in this order:
251 *
252 * /etc/IMEISV (sensible nibble order, not encrypted)
253 * Pirelli's encrypted IMEI record (Pirelli target only)
254 * hard-coded fallback and error indication
255 */
256
257 ret = ffs_file_read(CL_IMEI_FFS_PATH, imeiBufPtr, CL_IMEI_SIZE);
258 if (ret >= EFFS_OK) {
259 memcpy(stored_imei, imeiBufPtr, CL_IMEI_SIZE);
260 imei_flag = 1;
322 return CL_IMEI_OK; 261 return CL_IMEI_OK;
323 } else { 262 }
324 TRACE_ERROR("CL IMEI FATAL ERROR: IMEI not available!"); 263 ret = CL_IMEI_READ_IMEI_FAILED;
325 /* 264 #if CONFIG_TARGET_PIRELLI
326 * Notify the Frame entity about FATAL ERROR, but not in the case, 265 /* not yet implemented */
327 * if ACI is checking IMEI, because ACI will take trouble about it. 266 #endif
328 */ 267 TRACE_ERROR("CL IMEI FATAL ERROR: IMEI not available!");
329 if (imeiType != CL_IMEI_CONTROL_IMEI){ 268 memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE);
330 TRACE_ASSERT(ret == CL_IMEI_OK); 269 return ret;
331 } 270 #endif /* CONFIG_MOKOFFS */
332 return ret;
333 }
334 /*
335 * The feature flag FF_PROTECTED_IMEI is not enabled.
336 */
337 #else /* FF_PROTECTED_IMEI */
338
339 /*
340 * Return default CALYPSO+ IMEISV value
341 */
342 #ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM
343
344 TRACE_EVENT("CL IMEI INFO: return default IMEI-SV number");
345 memcpy(imeiBufPtr, C_DEFAULT_IMEISV_ESAMPLE, CL_IMEI_SIZE);
346
347 /*
348 * CL_IMEI_CALYPSO_PLATFORM or CL_IMEI_OTHER_PLATFORM is defined.
349 * Try to read the IMEI number from the old ffs:/pcm/IMEI file,
350 * if it failes, return default CALYPSO IMEISV value
351 */
352 #else /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
353 {
354 UBYTE version;
355 USHORT ret;
356 UBYTE buf[SIZE_EF_IMEI];
357
358 ret = pcm_ReadFile ((UBYTE *)EF_IMEI_ID, SIZE_EF_IMEI, buf, &version);
359 if(ret == PCM_OK){
360 TRACE_EVENT("CL IMEI INFO: return IMEI-SV number from ffs:/pcm/IMEI");
361 /*
362 * swap digits
363 */
364 imeiBufPtr[0] = ((buf[0] & 0xf0) >> 4) | ((buf[0] & 0x0f) << 4);
365 imeiBufPtr[1] = ((buf[1] & 0xf0) >> 4) | ((buf[1] & 0x0f) << 4);
366 imeiBufPtr[2] = ((buf[2] & 0xf0) >> 4) | ((buf[2] & 0x0f) << 4);
367 imeiBufPtr[3] = ((buf[3] & 0xf0) >> 4) | ((buf[3] & 0x0f) << 4);
368 imeiBufPtr[4] = ((buf[4] & 0xf0) >> 4) | ((buf[4] & 0x0f) << 4);
369 imeiBufPtr[5] = ((buf[5] & 0xf0) >> 4) | ((buf[5] & 0x0f) << 4);
370 imeiBufPtr[6] = ((buf[6] & 0xf0) >> 4) | ((buf[6] & 0x0f) << 4);
371 imeiBufPtr[7] = ((buf[7] & 0xf0) >> 4) | ((buf[7] & 0x0f) << 4);
372 /* store IMEI */
373 memcpy(stored_imei, imeiBufPtr, CL_IMEI_SIZE);
374 imei_flag = 1;
375
376 }else{
377 TRACE_EVENT("CL IMEI INFO: return default IMEI-SV number");
378 memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE);
379 }
380 }
381 #endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
382
383 return CL_IMEI_OK;
384
385 #endif /* FF_PROTECTED_IMEI */
386 #endif /* _SIMULATION_ */
387 } 271 }
388 272
389
390 #endif /* CL_IMEI_C */ 273 #endif /* CL_IMEI_C */