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

📄 cave.c

📁 brew代码里面的一个文件
💻 C
📖 第 1 页 / 共 3 页
字号:
nv_item.ssd_a.nam = CAVE_NAM_index;
qw_equ( nv_item.ssd_a.ssd, CAVE_SSD_A);
auth_put_nv_item( NV_SSD_A_I, &nv_item );

nv_item.ssd_b.nam = CAVE_NAM_index;
qw_equ( nv_item.ssd_b.ssd, CAVE_SSD_B);
auth_put_nv_item( NV_SSD_B_I, &nv_item );

MSG_MED("SSD updated", 0L, 0L, 0L);

return TRUE;

} /* CAVE_update_SSD */

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

FUNCTION CAVE_auth_signature

DESCRIPTION
  This function computes an authentication signature as specified in
  "Common Cryptographic Algorithms".

DEPENDENCIES
  CAVE_init must have been called before this function is called.

RETURN VALUE
  Returns the computed AUTH_SIGNATURE.

SIDE EFFECTS
  Changes value of CAVE_lfsr, CAVE_offset_1 and 2, CAVE_mixing_reg.

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

dword  CAVE_auth_signature
(
  dword     rand_challenge,
    /* The random number unique to this authentication challenge */

  dword     auth_data,
    /* 24 bits of data to be signed */

  boolean   use_new_SSD,
    /* TRUE if new_SSD_A and new_SSD_B are to be used, FALSE if the
       current SSD_A and SSD_B are to be used. */

  boolean   save_registers
    /* TRUE if this authentication is to be used as seed for message
       encryption and voice privacy, FALSE if not.  If TRUE, the
       saved_* variables will be updated. */

#ifdef FEATURE_OTASP_OTAPA  
  ,boolean   validating_spasm
    /* TRUE if we are calculating the auth_otapa for SPASM validation, 
       where SSD_AUTH input parameter is set to exclusive OR of SSD_A
       and A_KEY. */
#endif /* FEATURE_OTASP_OTAPA */
)

{
  qword  ssd;
    /* The version of Shared Secret Data to use for this computation. */

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

  dword  auth_signature;
    /* The authentication signature to be computed and returned. */

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

qw_equ(ssd, use_new_SSD ? CAVE_new_SSD_A : CAVE_SSD_A);
      /* Use the specified version of SSD. */

#ifdef FEATURE_OTASP_OTAPA
      /* If validating spasm, then SSD_AUTH input parameter is set to the 
         exclusive OR of SSD_A and A_KEY. */
if (validating_spasm)
  {
  for (R_index = 0; R_index <= 7; R_index++)
    {
    QW_BYTE(ssd, R_index) ^= QW_BYTE(CAVE_A_key, R_index);
    }
  }
#endif /* FEATURE_OTASP_OTAPA */

  MSG_MED( "Auth Sig rand_challenge %ld", rand_challenge, 0, 0 );
  MSG_MED( "Auth Sig auth_data %ld", auth_data, 0, 0 );

      /* Initialize all CAVE variables for an authentication signature, as
         specified in "Common Cryptographic Algorithms", Exhibit 2.3-1 */

CAVE_lfsr = rand_challenge ^ qw_hi(ssd) ^ qw_lo(ssd);
if (CAVE_lfsr == 0)                 /* Don't let the shift register be zero */
  {
  CAVE_lfsr = rand_challenge;
  }

                        /* Copy the Shared Secret Data into mixing_reg */
for (R_index = 0; R_index <= 7; R_index++)
  {
  CAVE_mixing_reg[R_index] = QW_BYTE(ssd, 7 - R_index);
  }

CAVE_mixing_reg[8] = CAVE_AAV;    /* Copy algorithm version into mixing_reg */

                        /* Copy the data to be signed into mixing_reg */
for (R_index = 9; R_index <= 11; R_index++)
  {
  CAVE_mixing_reg[R_index] = B_PTR(auth_data)[11 - R_index];
  }

                        /* Copy the ESN into mixing_reg */
for (R_index = 12; R_index <= 15; R_index++)
  {
  CAVE_mixing_reg[R_index] = B_PTR(CAVE_esn)[15 - R_index];
  }

CAVE_offset_1 = 128;         /* Initial values for CAVE_table offset */
CAVE_offset_2 = 128;

CAVE_rounds(8);         /* Perform 8 rounds of the CAVE algorithm */

                        /* Construct the signature from mixing_reg */
B_PTR(auth_signature)[3] = 0;
B_PTR(auth_signature)[2] = (CAVE_mixing_reg[0] ^ CAVE_mixing_reg[13]) & 0x03;
B_PTR(auth_signature)[1] =  CAVE_mixing_reg[1] ^ CAVE_mixing_reg[14];
B_PTR(auth_signature)[0] =  CAVE_mixing_reg[2] ^ CAVE_mixing_reg[15];

                        /* Save the variables if we're supposed to */
if (save_registers)
  {
  CAVE_saved_lfsr = CAVE_lfsr;
  CAVE_saved_offset_1 = CAVE_offset_1;
  CAVE_saved_offset_2 = CAVE_offset_2;
  CAVE_saved_rand = rand_challenge;
  CAVE_saved_data = auth_data;
  }

return (auth_signature);

} /* CAVE_auth_signature */

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

FUNCTION CAVE_roll_lfsr

DESCRIPTION
  This function performs a manipulation on the LFSR that is used
  repeatedly by the CMEA key and VPM generation process.

DEPENDENCIES
  None.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

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

LOCAL void  CAVE_roll_lfsr(void)
{

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

LFSR_A = CAVE_mixing_reg[0];
LFSR_B = CAVE_mixing_reg[1];
LFSR_C = CAVE_mixing_reg[14];
LFSR_D = CAVE_mixing_reg[15];

if (CAVE_lfsr == 0)                /* Don't let the shift register be zero */
  {
  CAVE_lfsr = CAVE_saved_rand;
  }
} /* CAVE_roll_lfsr */

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

FUNCTION CAVE_generate_key

DESCRIPTION
  This function generates the CMEA key (used for message encryption)
  and voice privacy mask for a call.

DEPENDENCIES
  CAVE_auth_signature must have been called with save_registers set
  to TRUE before this function may be called.

RETURN VALUE
  None.

SIDE EFFECTS
  Changes value of CAVE_lfsr, CAVE_offset_1 and 2, CAVE_mixing_reg.
  Also, it sets the flag used by other tasks (MC) to determine if it is
  OK to call the encryption routines.

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

void  CAVE_generate_key
(
  boolean do_VPM,
    /* Indicates whether or not the full VPM calculation is to be done */
  boolean *valid_CMEA_key_flag_ptr,
    /* Pointer allows immediate update of this flag for other tasks */
  boolean use_new_SSD
    /* If authr that was computed for re-auth response was based on new ssd, 
       this is set to TRUE */
)
{
  int    R_index;
    /* Index into the mixing_reg array */

  int    VPM_inx;
    /* Index into the voice privacy mask */

  int    i;
    /* Iteration counter */

  qword  ssd;
    /* The version of Shared Secret Data to base the keys on. */

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
qw_equ(ssd, use_new_SSD ? CAVE_new_SSD_B : CAVE_SSD_B);
      /* Use the specified version of SSD_B. */

      /* Initialize all CAVE variables for CMEA key and VPM generation, as
         specified in "Common Cryptographic Algorithms", Section 2.4 */

CAVE_lfsr = CAVE_saved_lfsr ^ qw_hi(ssd) ^ qw_lo(ssd);
if (CAVE_lfsr == 0)                /* Don't let the shift register be zero */
  {
  CAVE_lfsr = CAVE_saved_rand;
  }

                        /* Copy the Shared Secret Data into mixing_reg */
for (R_index = 0; R_index <= 7; R_index++)
  {
  CAVE_mixing_reg[R_index] = QW_BYTE(ssd, 7 - R_index);
  }

CAVE_mixing_reg[8] = CAVE_AAV;    /* Copy algorithm version into mixing_reg */

                        /* Copy the data that was signed by the original
                           Auth_Signature for this call into mixing_reg */
for (R_index = 9; R_index <= 11; R_index++)
  {
  CAVE_mixing_reg[R_index] = B_PTR(CAVE_saved_data)[11 - R_index];
  }

                        /* Copy the ESN into mixing_reg */
for (R_index = 12; R_index <= 15; R_index++)
  {
  CAVE_mixing_reg[R_index] = B_PTR(CAVE_esn)[15 - R_index];
  }

CAVE_offset_1 = CAVE_saved_offset_1; /* Restore state of CAVE_table offsets */
CAVE_offset_2 = CAVE_saved_offset_2;

/* Iteration 1: first pass through CAVE */
CAVE_rounds(8);         /* Perform 8 rounds of the CAVE algorithm */

/* Iteration 2: generation of first CMEA key parameters */
CAVE_roll_lfsr();
CAVE_rounds(4);         /* Perform 4 rounds of the CAVE algorithm */

CAVE_CMEA_key[0] = CAVE_mixing_reg[4] ^ CAVE_mixing_reg[8];
CAVE_CMEA_key[1] = CAVE_mixing_reg[5] ^ CAVE_mixing_reg[9];
CAVE_CMEA_key[2] = CAVE_mixing_reg[6] ^ CAVE_mixing_reg[10];
CAVE_CMEA_key[3] = CAVE_mixing_reg[7] ^ CAVE_mixing_reg[11];

/* Iteration 3: generation of next CMEA key parameters */
CAVE_roll_lfsr();
CAVE_rounds(4);         /* Perform 4 rounds of the CAVE algorithm */

CAVE_CMEA_key[4] = CAVE_mixing_reg[4] ^ CAVE_mixing_reg[8];
CAVE_CMEA_key[5] = CAVE_mixing_reg[5] ^ CAVE_mixing_reg[9];
CAVE_CMEA_key[6] = CAVE_mixing_reg[6] ^ CAVE_mixing_reg[10];
CAVE_CMEA_key[7] = CAVE_mixing_reg[7] ^ CAVE_mixing_reg[11];

/* At this point the CMEA key is valid */
*valid_CMEA_key_flag_ptr = TRUE;
MSG_MED("CMEA key calculated",0,0,0);

if (do_VPM)
  {
  /* Iteration 4 to 13: generation of VPM */
  VPM_inx = 0;
  for (i=0; i < 10; i++)
    {
    CAVE_roll_lfsr();
    CAVE_rounds(4);       /* Perform 4 rounds of the CAVE algorithm */
    for (R_index = 2; R_index <= 7; R_index++)
      {
      CAVE_VPM[VPM_inx++] =
        CAVE_mixing_reg[R_index] ^ CAVE_mixing_reg[R_index+6];
      }
    }

  /* Iteration 14: generation of last VPM bits */
  CAVE_roll_lfsr();
  CAVE_rounds(4);         /* Perform 4 rounds of the CAVE algorithm */
  for (R_index = 2; R_index <= 6; R_index++)
    {
    CAVE_VPM[VPM_inx++] =
      CAVE_mixing_reg[R_index] ^ CAVE_mixing_reg[R_index+6];
    }
  } /* end if (do_VPM) */
MSG_MED("VPM calculated",0,0,0);
} /* CAVE_generate_key */

#endif /* !FEATURE_UIM_RUIM || FEATURE_UIM_RUN_TIME_ENABLE */

/*===========================================================================

FUNCTION CAVE_tbox

DESCRIPTION
  This function performs the tbox primitive used in the CMEA
  message encryption algorithm.

DEPENDENCIES
  CMEA_key is used.

RETURN VALUE
  Returns the result of the tbox primitive.

SIDE EFFECTS
  None.

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

LOCAL byte CAVE_tbox
(
  byte  z
    /* Input to the tbox primitive */
)

{
  int    k_index;
    /* Index into the CAVE table */

  byte   temp;
    /* Computation variable as defined for the tbox; eventually returned. */

  int    i;
    /* Iteration counter */

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

k_index = 0;
temp = z;

for (i = 0; i < 4; i++)
  {
  temp ^= CAVE_CMEA_key[k_index++];
  temp += CAVE_CMEA_key[k_index++];      /* mod 256 */
  temp = z + CAVE_table[temp];      /* mod 256 */
  }

return temp;
} /* CAVE_tbox */

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

FUNCTION CAVE_encrypt

DESCRIPTION
  This function encrypts a message buffer, in place, using the CMEA
  algorithm from "Common Cryptographic Algorithms".

DEPENDENCIES
  CAVE_generate_key must have been called before this function is called.

RETURN VALUE
  None.  (But the message buffer is encrypted, in place.)

SIDE EFFECTS
  None.

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

void  CAVE_encrypt
(
  byte   msg_buf[],
    /* Message buffer to be encrypted */

  int    msg_len
    /* Number of bytes in the message buffer */
)

{
  int  msg_inx;
    /* Index into the message buffer */

  byte   k, z;
    /* Temporary computation variables defined by the CMEA algorithm */

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

/* First Manipulation */
z = 0;
for (msg_inx = 0; msg_inx < msg_len; msg_inx++)
  {
  msg_buf[msg_inx] += CAVE_tbox(z ^ (byte)msg_inx);  /* mod 256 */
  z += msg_buf[msg_inx];                        /* mod 256 */
  }

/* Second Manipulation */
for (msg_inx = 0; msg_inx < msg_len/2; msg_inx++)
  {
  msg_buf[msg_inx] ^= (msg_buf[msg_len - 1 - msg_inx] | 0x01);
  }

/* Third Manipulation */
z = 0;
for (msg_inx = 0; msg_inx < msg_len; msg_inx++)
  {
  k = CAVE_tbox(z ^ (byte)msg_inx);
  z += msg_buf[msg_inx];      /* mod 256 */
  msg_buf[msg_inx] -= k;      /* mod 256, no borrow */
  }

} /* CAVE_encrypt */

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

FUNCTION CAVE_private_lcm

DESCRIPTION
  This function returns the private long code mask for CDMA voice privacy.
  The private LCM is defined to be '01' concatenated with the 40 LSBs of VPM.

DEPENDENCIES
  CAVE_generate_key must have been called before this function is called.
  Depends on Intel byte order.

RETURN VALUE
  Returns the private long code mask.

SIDE EFFECTS
  None.

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

ulpn_type CAVE_private_lcm(void)
{
  ulpn_type lcm;
    /* The private LCM to be returned */

  byte      inx;
    /* Index into the LCM */

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

for (inx = 0; inx <= 3; inx++)
  {
  B_PTR(lcm.low)[inx] = CAVE_VPM[64 - inx];
  }

lcm.high = 0x0100 | CAVE_VPM[60];

return lcm;

} /* CAVE_private_lcm */

#ifdef FEATURE_UIM_RUIM
/*===========================================================================

FUNCTION CAVE_update_keys

DESCRIPTION
  This function updates the private long code mask for CDMA voice privacy.
  Also updates the CMEA key that is used by CAVE.

DEPENDENCIES
  Depends on Intel byte order.

RETURN VALUE
  None

SIDE EFFECTS
  Update the CMEA and VPM.

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

void CAVE_update_keys
(
  byte *data
)
{
  /* copy the first 8 bytes of key from RUIM into CMEA_key */
  memcpy(CAVE_CMEA_key, data, 8);

  /* copy the next 65 bytes of mask from RUIM into VPM */
  memcpy(CAVE_VPM, data+8, CAVE_VPM_SIZE);
}

#endif /* FEATURE_UIM_RUIM */

#endif /* FEATURE_AUTH */

⌨️ 快捷键说明

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