⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cave.c

📁 brew代码里面的一个文件
💻 C
📖 第 1 页 / 共 3 页
字号:
/*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*

                       C A V E   M O D U L E

GENERAL DESCRIPTION
  This module contains routines to support the CAVE (Cellular
  Authentication, Voice Privacy and Encryption) algorithm as specified
  in "Common Cryptographic Algorithms" called out in IS-95.

  This module is common to all hardware targets.

NOTES
  1. See "Common Cryptographic Algorithms" for explanations and
     specifications of all these algorithms.

  2. Most of the arrays specified in "Common Cryptographic Algorithms"
     are indexed backwards as compared to C arrays: XXX[0] is the
     MOST significant byte of XXX.  This module follows that convention
     for arrays, but keeps whole values in conventional byte order.
     Some code here depends on Intel byte order.

NOTICE
  Information embodied in this module may be subject to the export
  jurisdiction of the US Department of State as specified in the
  International Traffic in Arms Regulations (title 22 CFR parts
  120 through 130 inclusive).  A license issued by the Department
  of State is required for the export of such technical data.

EXTERNALIZED FUNCTIONS
  CAVE_init
    Initializes CAVE processing, at powerup or NAM change.

  CAVE_validate_A_key
    Checks a manually-entered A-key against its check digits.

  CAVE_update_A_key
    Stores a new A-key and clears out SSD.

  CAVE_generate_SSD
    Generates new A and B values of Shared Secret Data.

  CAVE_update_SSD
    Stores new A and B values of SSD.

  CAVE_auth_signature
    Computes and authentication signature.

  CAVE_encrypt
    Encrypts a message buffer using the CMEA algorithm.

  CAVE_private_lcm
    Returns the private long code mask to be used for CDMA voice privacy.

INITIALIZATION AND SEQUENCING REQUIREMENTS
  CAVE_init must be called once on powerup or NAM change, to set
  up the identity variables, before any other functions are called.

  CAVE_auth_signature must be called with save_registers set to TRUE,
  and CAVE_generate_key must be called, before any message encryption
  can be performed or the private long code mask can be returned.

   Copyright(c) 1994,1995,1996 QUALCOMM INCORPORATED.  All Rights Reserved.
   Copyright(c) 1999 QUALCOMM INCORPORATED.  All Rights Reserved.
*====*====*====*====*====*====*====*====*====*====*====*====*====*====*====*/


/*===========================================================================

                        EDIT HISTORY FOR MODULE

  This section contains comments describing changes made to the module.
  Notice that changes are listed in reverse chronological order.

  $PVCSPath: L:/src/asw/MSM5100/CP_REL_A/vcs/cave.c_v   1.4   09 Sep 2002 16:22:20   azafer  $
  $Header: //depot/asic/msmshared/1x/cp/MSMSHARED_CP_CDMA.02.00.64B/cave.c#1 $ $DateTime: 2004/08/24 16:28:29 $ $Author: louiel $

when       who     what, where, why
--------   ---     ----------------------------------------------------------
09/09/02   ts      Added support for Run Time R-UIM Enable feature
08/09/01   sb      Merged following changes from common archive:
                   06/19/01   ts      Moved the VPM size constant to this file.
                   06/13/01   ts      A change in the VPM octet offset has caused 
                                      a problem with CAVE_update_keys.  Changed 
				      the VPM size to use the proper size and not 
				      the offset.
05/25/01   ts      Added feature switches for new UIM server.
03/09/01   fas     Added include for customer.h to inhibit compiler warning.
06/28/00   cah     Removed MSG_FILE undef work around for nonRUIM builds.
05/30/00   ck      Added undef MSG_FILE to remove compiler warning.
05/24/00   ck      Added the function CAVE_update_keys() that sets the CMEA
                   and VPM keys based on the keys computed by the RUIM.
                   Featurised out most of the CAVE functionality based on
                   FEATURE_RUIM. 
04/06/00   va      Merged the following from MSM3100_CP.03.00.17
           ry      Added OTAPA support
08/13/99   jq      Removed the use of ROM, since it's no longer defined.
06/17/99   ck      Fixed the problem where the CMEA and VPM keys were computed
                   based on the old SSD during re-authentication.
05/10/99   kmp     Replaced T_AUTH with FEATURE_AUTH
04/08/99   ck      Removed the initialisation of SSD_A and SSD_B after the
                   update of A-Key by OTASP as it erased the previous contents 
                   of valid SSD.
03/18/99   ck      Merged in support for A-Key exchange and Re-Authentication
03/18/99   ck      Merged the change from rev 1.10 SPSW
                   Keyword 'const' inserted in front of the ROM macro. 
09/15/98   pms     Backed out _near pointers
09/04/98   pms     Neared the variables to save ROM space.
06/21/96   dna     Removed checksums for A-key, SSD-A and SSD-B.  We now make
                   them zero if unitialized and always consider them valid.
05/15/96   dna     CMEA key generation status now set ASAP.
04/24/96   dna     Now write checksum for zero'd SSD when changing A-Key.
08/23/95   dna     Checked in initial version.
04/19/94   ptw     Created module.

===========================================================================*/


/*===========================================================================

                     INCLUDE FILES FOR MODULE

===========================================================================*/

#include "comdef.h"
#include "target.h"
#include "customer.h"

#ifdef FEATURE_AUTH

/* Temporary change to rid msg_file compiler warning until msg fix is in */
#if defined( FEATURE_UIM_RUIM ) && !defined( FEATURE_UIM_RUN_TIME_ENABLE )
#undef MSG_FILE
#endif /* FEATURE_UIM_RUIM && !FEATURE_UIM_RUN_TIME_ENABLE */

#include "err.h"
#include "mccdma.h"
#include "msg.h"
#include "nv.h"
#include "qw.h"
#include "cave.h"
#include "ulpn.h"       /* For ulpn_type definition */
#include "auth.h"
#include "authi.h"
#include "crc.h"
#ifdef FEATURE_UIM_RUIM
#include "memory.h"
#endif /* FEATURE_UIM_RUIM */


/*===========================================================================

            LOCAL DEFINITIONS AND DECLARATIONS FOR MODULE

This section contains local definitions for constants, macros, types,
variables and other items needed by this module.

===========================================================================*/

#define  CAVE_VPM_SIZE  65
   /* Size of VPM in bytes. */

#define  CAVE_AAV   (0xC7)
   /* Authentication Algorithm Version */

LOCAL dword    CAVE_esn;
   /* The electronic serial number of this phone. */

LOCAL qword    CAVE_A_key;
   /* The current A_key in use for CAVE */

LOCAL qword    CAVE_SSD_A;
   /* The current A value of Shared Secret Data in use for CAVE */

LOCAL qword    CAVE_SSD_B;
   /* The current B value of Shared Secret Data in use for CAVE */

LOCAL qword    CAVE_new_SSD_A;
   /* A possible new A value of Shared Secret Data */

LOCAL qword    CAVE_new_SSD_B;
   /* A possible new B value of Shared Secret Data */

LOCAL byte     CAVE_NAM_index;
   /* Index of current NAM being used */

LOCAL dword CAVE_lfsr;
   /* The linear (actually non-linear) feedback shift register used
      in the CAVE algorithm. */

LOCAL dword    CAVE_saved_lfsr;
   /* Value of lfsr saved from the authentication that is to be used
      as seed for encryption and voice privacy */

LOCAL byte CAVE_mixing_reg[16];
   /* The mixing registers used in the CAVE algorithm */

LOCAL byte     CAVE_offset_1, CAVE_offset_2;
   /* Offsets into the CAVE table used in the CAVE algorithm */

LOCAL byte     CAVE_saved_offset_1, CAVE_saved_offset_2;
   /* Values of offset_1 and offset_2 saved from the authentication
      that is to be used as seed for encryption and voice privacy */

LOCAL dword    CAVE_saved_rand;
   /* Value of rand_challenge saved from the authentication that is
      to be used as seed for encryption and voice privacy */

LOCAL dword    CAVE_saved_data;
   /* Value of auth_data saved from the authentication that is to be used
      as seed for encryption and voice privacy */

LOCAL byte     CAVE_CMEA_key[8];
   /* Key used for message encryption */

LOCAL byte     CAVE_VPM[CAVE_VPM_SIZE];
   /* 520 bit voice privacy mask.  Actually, only the 40 LSBits of this
      are ever used.  VPM[64] is the least significant byte. */


/*-------------------------------------------------------------------------

      CAVE Table

   This table is taken from Exhibit 2-3 of "Common Cryptographic Algorithms"

   It is really two tables: the LS nibble of each entry is table0, and
                            the MS nibble of each entry is table1.

-------------------------------------------------------------------------*/

#define  LOMASK   0x0F        /* Mask all but the least significant nibble */
#define  HIMASK   0xF0        /* Mask all but the most significant nibble */

static byte const CAVE_table[256] = {
/* 0 */ 0xd9, 0x23, 0x5f, 0xe6, 0xca, 0x68, 0x97, 0xb0,
        0x7b, 0xf2, 0x0c, 0x34, 0x11, 0xa5, 0x8d, 0x4e,
/* 1 */ 0x0a, 0x46, 0x77, 0x8d, 0x10, 0x9f, 0x5e, 0x62,
        0xf1, 0x34, 0xec, 0xa5, 0xc9, 0xb3, 0xd8, 0x2b,
/* 2 */ 0x59, 0x47, 0xe3, 0xd2, 0xff, 0xae, 0x64, 0xca,
        0x15, 0x8b, 0x7d, 0x38, 0x21, 0xbc, 0x96, 0x00,
/* 3 */ 0x49, 0x56, 0x23, 0x15, 0x97, 0xe4, 0xcb, 0x6f,
        0xf2, 0x70, 0x3c, 0x88, 0xba, 0xd1, 0x0d, 0xae,
/* 4 */ 0xe2, 0x38, 0xba, 0x44, 0x9f, 0x83, 0x5d, 0x1c,
        0xde, 0xab, 0xc7, 0x65, 0xf1, 0x76, 0x09, 0x20,
/* 5 */ 0x86, 0xbd, 0x0a, 0xf1, 0x3c, 0xa7, 0x29, 0x93,
        0xcb, 0x45, 0x5f, 0xe8, 0x10, 0x74, 0x62, 0xde,
/* 6 */ 0xb8, 0x77, 0x80, 0xd1, 0x12, 0x26, 0xac, 0x6d,
        0xe9, 0xcf, 0xf3, 0x54, 0x3a, 0x0b, 0x95, 0x4e,
/* 7 */ 0xb1, 0x30, 0xa4, 0x96, 0xf8, 0x57, 0x49, 0x8e,
        0x05, 0x1f, 0x62, 0x7c, 0xc3, 0x2b, 0xda, 0xed,
/* 8 */ 0xbb, 0x86, 0x0d, 0x7a, 0x97, 0x13, 0x6c, 0x4e,
        0x51, 0x30, 0xe5, 0xf2, 0x2f, 0xd8, 0xc4, 0xa9,
/* 9 */ 0x91, 0x76, 0xf0, 0x17, 0x43, 0x38, 0x29, 0x84,
        0xa2, 0xdb, 0xef, 0x65, 0x5e, 0xca, 0x0d, 0xbc,
/* a */ 0xe7, 0xfa, 0xd8, 0x81, 0x6f, 0x00, 0x14, 0x42,
        0x25, 0x7c, 0x5d, 0xc9, 0x9e, 0xb6, 0x33, 0xab,
/* b */ 0x5a, 0x6f, 0x9b, 0xd9, 0xfe, 0x71, 0x44, 0xc5,
        0x37, 0xa2, 0x88, 0x2d, 0x00, 0xb6, 0x13, 0xec,
/* c */ 0x4e, 0x96, 0xa8, 0x5a, 0xb5, 0xd7, 0xc3, 0x8d,
        0x3f, 0xf2, 0xec, 0x04, 0x60, 0x71, 0x1b, 0x29,
/* d */ 0x04, 0x79, 0xe3, 0xc7, 0x1b, 0x66, 0x81, 0x4a,
        0x25, 0x9d, 0xdc, 0x5f, 0x3e, 0xb0, 0xf8, 0xa2,
/* e */ 0x91, 0x34, 0xf6, 0x5c, 0x67, 0x89, 0x73, 0x05,
        0x22, 0xaa, 0xcb, 0xee, 0xbf, 0x18, 0xd0, 0x4d,
/* f */ 0xf5, 0x36, 0xae, 0x01, 0x2f, 0x94, 0xc3, 0x49,
        0x8b, 0xbd, 0x58, 0x12, 0xe0, 0x77, 0x6c, 0xda
      };


/*-------------------------------------------------------------------------
      Macros to access individual bytes of the LFSR

   These macros exist to make the code in this module read more like
   the pseudocode in "Common Cryptographic Algorithms".

   Note: these macros are lvalues, so you can say LFSR_A = x.

   Caution: the macros depend on Intel byte order.
-------------------------------------------------------------------------*/

#define  LFSR_A   (B_PTR(CAVE_lfsr)[3])
#define  LFSR_B   (B_PTR(CAVE_lfsr)[2])
#define  LFSR_C   (B_PTR(CAVE_lfsr)[1])
#define  LFSR_D   (B_PTR(CAVE_lfsr)[0])

#if !defined (FEATURE_UIM_RUIM) || defined (FEATURE_UIM_RUN_TIME_ENABLE)

/*===========================================================================

FUNCTION CAVE_init

DESCRIPTION
  This function is called to perform initialization for the CAVE
  operations.  This mainly involves setting some variables from their
  values in semi-permanent memory.

DEPENDENCIES
  This function should only be called once on powerup or NAM change,
  or when the A_Key is changed.

RETURN VALUE
  AUTH_INIT_OK         if initialization is successful
  AUTH_UNINITIALIZED   if initialization fails

SIDE EFFECTS
  None.

===========================================================================*/

auth_init_status_type CAVE_init
(
  byte    NAM_index
      /* NAM which CAVE variables will be taken from */
)

{
  nv_item_type nv_item;
    /* Item to hold values retrieved from NV */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

/* --------------------------------------------------
** Read the ESN first so that no matter what happens,
** the ESN is valid for use in CAVE_validate_A_key().
** -------------------------------------------------- */

#if (TG!=T_PC)
(void) auth_get_nv_item(NV_ESN_CHKSUM_I, &nv_item);
if (nv_item.esn_chksum.chksum != NV_VALID_ESN_CHKSUM)
  {
  ERR("Invalid ESN", 0, 0, 0);
  return (AUTH_UNINITIALIZED);
  }
#endif

(void) auth_get_nv_item( NV_ESN_I, &nv_item );
CAVE_esn = nv_item.esn.esn;

/* ---------------------------------------------
** The a_key_checksum is now ignored, and zero
** is assumed if the a_key isn't available.
** --------------------------------------------- */

nv_item.a_key.nam = NAM_index;
if (auth_get_nv_item( NV_A_KEY_I, &nv_item ) == NV_DONE_S)
  {
  qw_equ( CAVE_A_key, nv_item.a_key.key );
  }
else
  {
  MSG_HIGH("Uninitialized value of A-key", 0, 0, 0);
  qw_set( CAVE_A_key, 0L, 0L );
  }

/* -------------------------------------------
** SSD checksums are no longer used, and zero
** is assumed for SSD if it is not available.
** ------------------------------------------- */

nv_item.ssd_a.nam = NAM_index;
if (auth_get_nv_item( NV_SSD_A_I, &nv_item ) == NV_DONE_S)
  {
  qw_equ( CAVE_SSD_A, nv_item.ssd_a.ssd );
  }
else
  {
  MSG_HIGH("Uninitialized value of SSD A", 0, 0, 0);
  qw_set( CAVE_SSD_A, 0L, 0L );
  }

nv_item.ssd_b.nam = NAM_index;
if (auth_get_nv_item( NV_SSD_B_I, &nv_item ) == NV_DONE_S)
  {
  qw_equ( CAVE_SSD_B, nv_item.ssd_b.ssd );
  }
else
  {
  MSG_HIGH("Uninitialized value of SSD B", 0, 0, 0);
  qw_set( CAVE_SSD_B, 0L, 0L );
  }

CAVE_NAM_index = NAM_index;

MSG_MED("CAVE initialized", 0L, 0L, 0L);
return (AUTH_INIT_OK);

} /* CAVE_init */


/*===========================================================================

FUNCTION CAVE_LFSR_cycle

DESCRIPTION
  This function cycles the linear feedback shift register (lfsr) once.
  It implements the LFSR specified in "Common Cryptographic Algorithms."

DEPENDENCIES
  None.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

LOCAL void CAVE_LFSR_cycle(void)
{
boolean  new_bit;
    /* The new bit to shift in on the left */

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
                     /* Compute the new bit to shift in.  It is the XOR
                        of four specific bits from the old state value. */
                     /*lint -e514  Yes, I mean to XOR Booleans. */
new_bit =   ((LFSR_B & 0x40) != 0 )
          ^ ((LFSR_D & 0x04) != 0 )
          ^ ((LFSR_D & 0x02) != 0 )
          ^ ((LFSR_D & 0x01) != 0 ) ;
                     /*lint -restore */
      /* This isn't very efficient.  Keep it straightforward for now. */

CAVE_lfsr >>= 1;          /* Shift the shift register */

                     /* Bring in the new bit */
if (new_bit != 0)
  {
  CAVE_lfsr |= 0x80000000L;
  }
} /* CAVE_LFSR_cycle */


/*===========================================================================

FUNCTION CAVE_rotate_right_registers

DESCRIPTION
  This function rotates the mixing_reg[] array, considered as a single
  128-bit value, right by one place.  The former LSbit becomes the new
  MSbit.

  Notice that mixing_reg[0] is consider the MSbyte.

DEPENDENCIES
  None.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

LOCAL void  CAVE_rotate_right_registers( void )

{
  boolean   new_bit;
    /* The new bit to shift in on the left */

  int       R_index;
    /* Index into the mixing_reg array */

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
         /* Pick off the old LSbit for end-around-carry */
new_bit = CAVE_mixing_reg[15] & 0x01;

         /* Shift right bytewise */
for (R_index = 15; R_index >= 1; R_index--)
  {
  CAVE_mixing_reg[R_index] >>= 1;             /* Shift a byte */
  if (CAVE_mixing_reg[R_index-1] & 0x01)      /* Propagate the carry bit */
    {
    CAVE_mixing_reg[R_index] |= 0x80;
    }
  }

CAVE_mixing_reg[0] >>= 1;                     /* Shift the last byte */
if (new_bit)                             /* Bring in the end-around carry */
  {
  CAVE_mixing_reg[0] |= 0x80;
  }

} /* CAVE_rotate_right_registers */


/*===========================================================================

FUNCTION CAVE_ROUNDS

DESCRIPTION
  This function performs the specified number of rounds of the CAVE
  algorithm.  It operates on the values found in the regional mixing_reg,
  and leaves its results there.

  Note that variable names and the structure of this function follow
  the pseudocode definition given in Exhibit 2-2 of "Common Cryptographic
  Algorithms".

DEPENDENCIES
  The regionals mixing_reg, lfsr, offset_1, and offset_2 must be properly
  initialized before calling this function.

RETURN VALUE
  None.

SIDE EFFECTS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -