diff gsm-fw/comlib/cl_imei.c @ 664:d36f647c2432

gsm-fw/comlib: initial import of TI's source cl_des.c and cl_imei.c are from the Leonardo semi-src; others are from LoCosto
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 28 Sep 2014 05:09:53 +0000
parents
children b34e5351438e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm-fw/comlib/cl_imei.c	Sun Sep 28 05:09:53 2014 +0000
@@ -0,0 +1,390 @@
+/*
++-----------------------------------------------------------------------------
+|  Project :  COMLIB
+|  Modul   :  cl_imei.c
++-----------------------------------------------------------------------------
+|  Copyright 2002 Texas Instruments Berlin, AG
+|                 All rights reserved.
+|
+|                 This file is confidential and a trade secret of Texas
+|                 Instruments Berlin, AG
+|                 The receipt of or possession of this file does not convey
+|                 any rights to reproduce or disclose its contents or to
+|                 manufacture, use, or sell anything it may describe, in
+|                 whole, or in part, without the specific written consent of
+|                 Texas Instruments Berlin, AG.
++-----------------------------------------------------------------------------
+|  Purpose :  Definitions of common library functions: IMEI decryption with
+              DES algorithm
++-----------------------------------------------------------------------------
+*/
+/*
+ *  Version 1.0
+ */
+
+/**********************************************************************************/
+
+/*
+NOTE:
+*/
+
+/**********************************************************************************/
+
+#ifndef CL_IMEI_C
+#define CL_IMEI_C
+
+#include "typedefs.h"
+#include "vsi.h"        /* to get a lot of macros */
+
+#ifndef _SIMULATION_
+#include "ffs/ffs.h"
+#include "config/chipset.cfg"
+#include "config/board.cfg"
+#include "memif/mem.h"
+#include "pcm.h"
+#endif /* ifdef SIMULATION */
+
+#include "cl_imei.h"
+#include "cl_des.h"
+#include <string.h>
+
+#if defined(CL_IMEI_CALYPSO_PLUS_PLATFORM) && defined(FF_PROTECTED_IMEI)
+#include "secure_rom/secure_rom.h"
+#endif
+
+static UBYTE stored_imei[CL_IMEI_SIZE]; /* when the imei is read once, the value
+                                             is stored in this buffer */
+static UBYTE imei_flag = 0;  /* this flag indicates, if IMEI was successful read
+                                and is  stored in the stored_imei buffer */
+
+#if !defined (CL_IMEI_CALYPSO_PLUS_PLATFORM)
+/* Default IMEISV for D-Sample 00440000-350-111-20 */
+const  UBYTE C_DEFAULT_IMEISV_DSAMPLE[CL_IMEI_SIZE] =
+             {0x00, 0x44, 0x00, 0x00, 0x35, 0x01, 0x11, 0x20};
+#define CL_IMEI_FFS_PATH   "/gsm/imei.enc"
+#endif /* CL_IMEI_CALYPSO_PLATFORM */
+
+#ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM
+/* Default IMEISV for E-Sample 00440000-351-222-30 */
+const  UBYTE C_DEFAULT_IMEISV_ESAMPLE[CL_IMEI_SIZE] =
+             {0x00, 0x44, 0x00, 0x00, 0x35, 0x12, 0x22, 0x30};
+#endif  /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
+
+/*==== FUNCTIONS ==================================================*/
+#ifdef FF_PROTECTED_IMEI
+
+#ifdef CL_IMEI_CALYPSO_PLATFORM
+/*
++------------------------------------------------------------------------------
+| Function    : get_dieID
++------------------------------------------------------------------------------
+| Description : the function reads the Die-ID from base band processor and
+|               extracts it from 4 BYTEs to 8 BYTEs.
+|
+| Parameters  : inBufSize  - size of buffer where to store Die ID, min.8 BYTE
+|               *outBufPtr - pointer to buffer where to store the Die ID
+| Return      : void
++------------------------------------------------------------------------------
+*/
+LOCAL void get_dieID(USHORT inBufSize, UBYTE *outBufPtr)
+{
+  int i;
+  USHORT *outBuf16 = (USHORT*)&outBufPtr[0];
+  volatile USHORT *reg_p = (USHORT *) CL_IMEI_DIE_ID_REG;
+
+  TRACE_FUNCTION("get_dieID()");
+
+  if(inBufSize < CL_IMEI_DIE_ID_SIZE){
+    TRACE_ERROR("CL IMEI ERROR: buffer size for Die ID to short!");
+  }
+#ifdef IMEI_DEBUG
+  TRACE_EVENT_P1("CL IMEI INFO: Die-ID address(0x%x)", CL_IMEI_DIE_ID_REG);
+#endif
+  for (i = 0; i < CL_IMEI_DIE_ID_SIZE; i++) {
+    /* Die ID is 4 BYTE long, extract it to 8 BYTE. */
+    outBuf16[i] = (USHORT)(*(UINT8*)(reg_p)++);
+  }
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : ffs_get_imeisv
++------------------------------------------------------------------------------
+| Description : the function reads IMEI from FFS
+|
+| Parameters  : inBufSize  - size of buffer where to store IMEI, min. 8 BYTE
+|               *outBufPtr - pointer to buffer where to store the IMEI
+| Return      :              0 - OK
+|                           <0 - ERROR
++------------------------------------------------------------------------------
+*/
+LOCAL BYTE ffs_get_imeisv (USHORT inBufSize, UBYTE *outBufPtr)
+{
+  UBYTE i;
+  UBYTE isdid_buf[CL_IMEI_ISDID_SIZE];
+  UBYTE r_dieId[CL_DES_KEY_SIZE]; /* read Die ID */
+  UBYTE d_dieId[CL_DES_KEY_SIZE]; /* deciphered Die ID */
+  SHORT ret;
+
+  TRACE_FUNCTION("ffs_get_imeisv()");
+
+  if(inBufSize < CL_IMEI_SIZE){
+    TRACE_ERROR("CL IMEI ERROR: buffer size for IMEI to short!");
+    return CL_IMEI_ERROR;
+  }
+
+  /*
+   * Read ISDID(enciphered IMEISV+DieID) from FFS.
+   */
+  if((ret = ffs_file_read(CL_IMEI_FFS_PATH, isdid_buf, CL_IMEI_ISDID_SIZE)) >= EFFS_OK)
+  {
+   /*
+    * Read Die ID for using as DES key
+    */
+    get_dieID(CL_DES_KEY_SIZE, r_dieId);
+   /*
+    * Call DES algorithm routine
+    */
+    /* decipher first 8 BYTEs */
+    cl_des(&isdid_buf[0], r_dieId, outBufPtr, CL_DES_DECRYPTION);
+    /* decipher the rest 8 BYTEs */
+    cl_des(&isdid_buf[CL_DES_BUFFER_SIZE], r_dieId, d_dieId, CL_DES_DECRYPTION);
+    if(!memcmp(d_dieId, r_dieId, CL_DES_KEY_SIZE))
+    {
+      /* Die ID is valid  */
+      ret = CL_IMEI_OK;
+    } else {/* Die ID is corrupted */
+      char pr_buf[126];
+      TRACE_ERROR("CL IMEI ERROR: Die ID is corrupted");
+      sprintf(pr_buf,"Read DieID: %02x %02x %02x %02x %02x %02x %02x %02x",
+                      r_dieId[0], r_dieId[1], r_dieId[2], r_dieId[3],
+                      r_dieId[4], r_dieId[5], r_dieId[6], r_dieId[7]);
+      TRACE_ERROR(pr_buf);
+      sprintf(pr_buf,"Deciphered DieID: %02x %02x %02x %02x %02x %02x %02x %02x",
+                      d_dieId[0], d_dieId[1], d_dieId[2], d_dieId[3],
+                      d_dieId[4], d_dieId[5], d_dieId[6], d_dieId[7]);
+      TRACE_ERROR(pr_buf);
+
+      ret = CL_IMEI_INVALID_DIE_ID;
+    }
+  } else {
+    ret = CL_IMEI_READ_IMEI_FAILED;
+  }
+
+    return ret;
+
+}/* ffs_get_imeisv() */
+#endif /* CL_IMEI_CALYPSO_PLATFORM */
+
+
+#ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM
+/*
++------------------------------------------------------------------------------
+| Function    : securerom_get_imeisv
++------------------------------------------------------------------------------
+| Description : the function reads IMEI from Secure ROM
+|
+| Parameters  : inBufSize  - size of buffer where to store IMEI, min. 8 BYTE
+|               *outBufPtr - pointer to buffer where to store the IMEI
+| Return      :              0 - OK
+|                           <0 - ERROR
++------------------------------------------------------------------------------
+*/
+LOCAL BYTE securerom_get_imeisv (USHORT inBufSize, UBYTE *outBufPtr)
+{
+  BYTE ret;
+
+  TRACE_FUNCTION("securerom_get_imeisv()");
+
+  if((ret = securerom_drv(inBufSize, outBufPtr)) == CL_IMEI_OK){
+    return CL_IMEI_OK;
+  } else {
+    return CL_IMEI_READ_IMEI_FAILED;
+  }
+}
+#endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
+
+/*
++------------------------------------------------------------------------------
+| Function    : get_secure_imeisv
++------------------------------------------------------------------------------
+| Description : the function reads IMEI either from FFS or from Secure ROM of
+|               from other locations depended on hardware platform
+|
+| Parameters  :     inBufSize  - size of buffer where to store IMEI, min. 8 BYTE
+|                   *outBufPtr - pointer to buffer where to store the IMEI
+| Return      :              0 - OK
+|               negative value - ERROR
++------------------------------------------------------------------------------
+*/
+LOCAL BYTE get_secure_imeisv(USHORT inBufSize, UBYTE *outBufPtr)
+{
+  BYTE ret = 0;
+  UBYTE chipset = CHIPSET;
+  UBYTE board = BOARD;
+
+  TRACE_FUNCTION("get_secure_imeisv()");
+
+/*
+ * SW is running on Calypso platform (D-Sample)
+ */
+#ifdef CL_IMEI_CALYPSO_PLATFORM
+  /*
+   * Read IMEI from FFS inclusive deciphering with DES.
+   */
+  if((ret = ffs_get_imeisv (inBufSize, outBufPtr)) == CL_IMEI_OK)
+  {
+    /* store IMEI */
+    memcpy(stored_imei, outBufPtr, CL_IMEI_SIZE);
+    imei_flag = 1;
+    return CL_IMEI_OK;
+  }
+#else /* CL_IMEI_CALYPSO_PLATFORM */
+/*
+ * SW is running on Calypso plus platform (E-Sample)
+ */
+#ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM
+  if((ret = securerom_get_imeisv (inBufSize, outBufPtr)) == CL_IMEI_OK)
+  {
+    /* store IMEI */
+    memcpy(stored_imei, outBufPtr, CL_IMEI_SIZE);
+    imei_flag = 1;
+    return CL_IMEI_OK;
+  }
+#else /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
+/*
+ * SW is running on an other platform (neither Calypso nor Calypso plus)
+ */
+#ifdef CL_IMEI_OTHER_PLATFORM
+  {
+    TRACE_EVENT_P2("CL IMEI WARNING: unknown hardware: board=%d, chipset=%d, return default imei",
+                                                                             board, chipset);
+    memcpy(outBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE);
+    return CL_IMEI_OK;
+  }
+#endif /* CL_IMEI_OTHER_PLATFORM */
+#endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
+#endif  /* CL_IMEI_CALYPSO_PLATFORM */
+
+  return ret; /* get_secure_imeisv is failed, return error code  */
+
+} /* get_secure_imeisv() */
+
+
+#endif /* FF_PROTECTED_IMEI */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cl_get_imeisv
++------------------------------------------------------------------------------
+| Description : Common IMEI getter function
+|
+| Parameters  : imeiBufSize  - size of buffer where to store IMEI, min 8 BYTEs
+|               *imeiBufPtr  - pointer to buffer where to store the IMEI
+|               imeiType     - indicates, if the IMEI should be read from
+|                              FFS/Secure ROM (value=CL_IMEI_GET_SECURE_IMEI) or
+|                              if the already read and stored IMEI (if available)
+|                              should be delivered (value=CL_IMEI_GET_STORED_IMEI)
+|                              The second option should be used only by ACI or
+|                              BMI to show the IMEISV on mobile's display or
+|                              in terminal window, e.g. if user calls *#06#.
+|                              For IMEI Control reason (used by ACI), the value
+|                              has to be CL_IMEI_CONTROL_IMEI
+| Return      :           OK - 0
+|                      ERROR - negative values
++------------------------------------------------------------------------------
+*/
+extern BYTE cl_get_imeisv(USHORT imeiBufSize, UBYTE *imeiBufPtr, UBYTE imeiType)
+{
+  BYTE ret = 0;
+
+  TRACE_FUNCTION("cl_get_imeisv()");
+
+#ifdef _SIMULATION_
+    memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE);
+    return CL_IMEI_OK;
+#else /* _SIMULATION_ */
+
+#ifdef FF_PROTECTED_IMEI
+  /*
+   * The user has required a stored IMEI. If it has been already read
+   * and stored, so return stored IMEI
+   */
+  if((imeiType == CL_IMEI_GET_STORED_IMEI) && (imei_flag == 1)){
+    memcpy(imeiBufPtr, stored_imei, CL_IMEI_SIZE);
+    return CL_IMEI_OK;
+  }
+  /*
+   * The user has required a secure IMEI. Read IMEI from FFS or from Secure ROM
+   */
+  if((ret = get_secure_imeisv(imeiBufSize, imeiBufPtr)) == CL_IMEI_OK)
+  {
+    return CL_IMEI_OK;
+  } else {
+    TRACE_ERROR("CL IMEI FATAL ERROR: IMEI not available!");
+    /*
+     * Notify the Frame entity about FATAL ERROR, but not in the case,
+     * if ACI is checking IMEI, because ACI will take trouble about it.
+     */
+    if (imeiType != CL_IMEI_CONTROL_IMEI){
+      TRACE_ASSERT(ret == CL_IMEI_OK);
+    }
+    return ret;
+  }
+/* 
+ * The feature flag FF_PROTECTED_IMEI is not enabled.
+ */
+#else /* FF_PROTECTED_IMEI */
+
+/*
+ * Return default CALYPSO+ IMEISV value
+ */
+#ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM
+
+  TRACE_EVENT("CL IMEI INFO: return default IMEI-SV number");
+  memcpy(imeiBufPtr, C_DEFAULT_IMEISV_ESAMPLE, CL_IMEI_SIZE);
+
+/*
+ * CL_IMEI_CALYPSO_PLATFORM or CL_IMEI_OTHER_PLATFORM is defined.
+ * Try to read the IMEI number from the old ffs:/pcm/IMEI file, 
+ * if it failes, return default CALYPSO IMEISV value
+ */
+#else /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
+  {
+    UBYTE version;
+    USHORT ret;
+    UBYTE buf[SIZE_EF_IMEI];
+ 
+    ret = pcm_ReadFile ((UBYTE *)EF_IMEI_ID, SIZE_EF_IMEI, buf, &version);
+    if(ret == PCM_OK){
+      TRACE_EVENT("CL IMEI INFO: return IMEI-SV number from ffs:/pcm/IMEI");
+      /*
+       * swap digits
+       */
+      imeiBufPtr[0] = ((buf[0] & 0xf0) >> 4) | ((buf[0] & 0x0f) << 4);
+      imeiBufPtr[1] = ((buf[1] & 0xf0) >> 4) | ((buf[1] & 0x0f) << 4);
+      imeiBufPtr[2] = ((buf[2] & 0xf0) >> 4) | ((buf[2] & 0x0f) << 4);
+      imeiBufPtr[3] = ((buf[3] & 0xf0) >> 4) | ((buf[3] & 0x0f) << 4);
+      imeiBufPtr[4] = ((buf[4] & 0xf0) >> 4) | ((buf[4] & 0x0f) << 4);
+      imeiBufPtr[5] = ((buf[5] & 0xf0) >> 4) | ((buf[5] & 0x0f) << 4);
+      imeiBufPtr[6] = ((buf[6] & 0xf0) >> 4) | ((buf[6] & 0x0f) << 4);
+      imeiBufPtr[7] = ((buf[7] & 0xf0) >> 4) | ((buf[7] & 0x0f) << 4);
+      /* store IMEI */
+      memcpy(stored_imei, imeiBufPtr, CL_IMEI_SIZE);
+      imei_flag = 1;
+      
+    }else{
+      TRACE_EVENT("CL IMEI INFO: return default IMEI-SV number");
+      memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE);
+    }
+  }
+#endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */
+
+  return CL_IMEI_OK;
+
+#endif /* FF_PROTECTED_IMEI */
+#endif /* _SIMULATION_ */
+}
+
+
+#endif /* CL_IMEI_C */