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

📄 cave.c

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

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

LOCAL void  CAVE_rounds
(
  int  n_rounds
    /* The number of rounds of the CAVE algorithm to be performed. */
)

{
  int    round;
    /* Counter keeping track of how many rounds have been performed */

  byte   temp_reg0;
    /* Storage for mixing_reg[0] for end-around shift into mixing_reg[15] */

  byte   low_nibble, high_nibble;
    /* Temporary variables used in the CAVE algorithm */

  byte   T[16];
    /* Temporary array used to shuffle the mixing_reg array */

  byte   T_inx;
    /* Index into the temporary array T, used for shuffling.
       Exhibit 2-2 calls this (among other variables) "temp" */

  byte   fail_count;
    /* Counter of how many times the scramble has been performed,
       with a match to mixing_reg[] each time.  After 32 failures,
       we'll just increment the shift register and go on anyway. */

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

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

for (round = n_rounds-1; round >= 0; round--)
  {
  temp_reg0 = CAVE_mixing_reg[0];       /* Save R0 for later use */

  for (R_index = 0; R_index <= 15; R_index++)
    {
    fail_count = 0;
    for (;;)
      {
      CAVE_offset_1 += LFSR_A ^ CAVE_mixing_reg[R_index];
      low_nibble = CAVE_table[CAVE_offset_1] & LOMASK;
      if (low_nibble == (CAVE_mixing_reg[R_index] & LOMASK))
        {
        CAVE_LFSR_cycle();
        if (++fail_count == 32)
          {
          LFSR_D++;                 /* mod 256 */
          break;
          }
        }
      else
        {
        break;
        }
      }/* for (;;) */

    fail_count = 0;
    for (;;)
      {
      CAVE_offset_2 += LFSR_B ^ CAVE_mixing_reg[R_index];
      high_nibble = CAVE_table[CAVE_offset_2] & HIMASK;
      if (high_nibble == (CAVE_mixing_reg[R_index] & HIMASK))
        {
        CAVE_LFSR_cycle();
        if (++fail_count == 32)
          {
          LFSR_D++;
          break;
          }
        }
      else
        {
        break;
        }
      }/* for (;;) */

    if (R_index == 15)
      {
      CAVE_mixing_reg[ 15    ] = temp_reg0 ^ low_nibble ^ high_nibble;
      }
    else
      {
      CAVE_mixing_reg[R_index] =
        CAVE_mixing_reg[R_index+1] ^ low_nibble ^ high_nibble;
      }

    CAVE_LFSR_cycle();

    } /* for R_index */

  CAVE_rotate_right_registers();

   /* Shuffle the mixing registers into temporary array T */
  for (R_index = 0; R_index <= 15; R_index++)
    {
    T_inx = CAVE_table[16*round + R_index] & LOMASK;
    T[T_inx] = CAVE_mixing_reg[R_index];
    }
   /*lint -esym(771,T) : it looks like T might not be initialized
     completely, but since the low nibble of CAVE_table[k] is a
     permutation for any fixed k, this in fact fills up the T array. */

   /* Copy temporary array T back into the registers */
  for (R_index = 0; R_index <= 15; R_index++)
    {
    CAVE_mixing_reg[R_index] = T[R_index];
    }
  } /* for round */
} /* cave_rounds */

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

FUNCTION CAVE_CALC_CHECKSUM

DESCRIPTION
  This function calculates the checksum value for a given A key, according
  to the procedure described in "Common Cryptographic Algorithms, Revision
  A"

DEPENDENCIES
  CAVE_init must be called before calling this function.
  Depends on Intel byte order.

RETURN VALUE
  Returns the calculated checksum value.

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

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

static dword CAVE_calc_checksum
(
  qword  A_key_under_test
    /* The value of the A-key to use in checksum calculation */
)
{
  dword  answer;
    /* The value computed as the check signature of the proposed A-key */

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

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

      /* Initialize all CAVE variables for A-key verification, as
         specified in "Common Cryptographic Algorithms", Exhibit 2.1-1 */

if ( qw_hi(A_key_under_test) != 0 )
  {
  CAVE_lfsr = qw_hi(A_key_under_test);
  }
else                          /* Don't let the shift register be zero */
  {
  CAVE_lfsr = CAVE_esn;
  }
                        /* Copy the candidate A-key into mixing_reg */
for (R_index = 0; R_index <= 7; R_index++)
  {
  CAVE_mixing_reg[R_index] = QW_BYTE(A_key_under_test, 7 - R_index);
  }

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

                        /* Copy the candidate A-key into mixing_reg again */
for (R_index = 9; R_index <= 11; R_index++)
  {
  CAVE_mixing_reg[R_index] = QW_BYTE(A_key_under_test, 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 check value out of mixing_reg */
B_PTR(answer)[3] = 0;
B_PTR(answer)[2] = ( CAVE_mixing_reg[0] ^ CAVE_mixing_reg[13] ) & 0x03;
B_PTR(answer)[1] =   CAVE_mixing_reg[1] ^ CAVE_mixing_reg[14];
B_PTR(answer)[0] =   CAVE_mixing_reg[2] ^ CAVE_mixing_reg[15];

return (answer);

} /* end CAVE_calc_checksum() */

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

FUNCTION CAVE_validate_A_key

DESCRIPTION
  This function checks the internal check digits of a manually-entered
  authentication key.

  The manually entered key consists of two parts.  The last six digits,
  taken as a numeric value, are the check digits.  The first 0 to 20
  digits, taken as a numeric value, is the A-key.  This function runs
  the A-key (and some other stuff) through the CAVE algorithm.  The
  output should match the value in the check digits.

DEPENDENCIES
  CAVE_init must be called before calling this function.

RETURN VALUE
  Returns TRUE if the A-key is validated, FALSE if not.

SIDE EFFECTS
  None.

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

boolean  CAVE_validate_A_key
(
  const byte full_A_key[AUTH_A_KEY_DIGITS]
    /* A-key to be validated, given as ascii digits */
)

{
  qword  A_key_under_test;
    /* A_key to check, in binary form */
  dword entered_checksum;
    /* Checksum entered, in binary form */
  word   i;
    /* Index */

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

qw_set( A_key_under_test, 0L, 0L );
entered_checksum = 0L;

      /* Convert A_key to 64-bit representation */
for (i = 0; i < CAVE_DATA_DIGITS; i++)
  {
  qw_mul( A_key_under_test, A_key_under_test, 10L );
  qw_inc( A_key_under_test, (dword)(full_A_key[i] - '0'));
  }

    /* Convert checksum */
for (i = 0; i < CAVE_CHECKSUM_DIGITS; i++)
  {
  entered_checksum = (entered_checksum * 10) +
                   (full_A_key[i + CAVE_DATA_DIGITS] - '0');
  }

      /* Check if calculated checksum matches entered value */
if (entered_checksum == CAVE_calc_checksum( A_key_under_test ))
  {
  MSG_MED("A-key validated successfully", 0L, 0L, 0L);
  return TRUE;
  }
else
  {
  MSG_HIGH("A-key invalid", 0L, 0L, 0L);
  return FALSE;
  }

} /* CAVE_validate_A_key */

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

FUNCTION CAVE_update_A_key

DESCRIPTION
  This function installs a new A-key in the phone.

DEPENDENCIES
  None.

RETURN VALUE
  Returns TRUE if the A-key is updated successfully, FALSE if not.

SIDE EFFECTS
  NV is updated: the new A-key is stored, and SSD is cleared.

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

boolean  CAVE_update_A_key
(
  const byte full_A_key[AUTH_A_KEY_DIGITS],
    /* A-key to be put into NV, given as ascii digits */

  byte NAM_index
    /* Which NAM is to be updated */
)
{
  qword  new_A_key;
    /* 64 bit representation of the new A_key */

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

  word i;
    /* index */
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

qw_set( new_A_key, 0L, 0L );

/* -------------------------------------------------------------
** Convert A_key to 64-bit representation.  The last digits in
** the array are a checksum, which is not used in this function.
** ------------------------------------------------------------- */
for (i = 0; i < CAVE_DATA_DIGITS; i++)
  {
  qw_mul( new_A_key, new_A_key, 10L );
  qw_inc( new_A_key, (dword)(full_A_key[i] - '0'));
  }

qw_equ(CAVE_A_key, new_A_key);               /* Accept the new A-Key */
qw_set(CAVE_SSD_A, 0L, 0L);                  /* Clear out SSD */
qw_set(CAVE_SSD_B, 0L, 0L);

nv_item.a_key.nam = NAM_index;
qw_equ( nv_item.a_key.key, CAVE_A_key);
auth_put_nv_item( NV_A_KEY_I, &nv_item );

/* ---------------------------
** Store zero'd out SSD in NV.
** --------------------------- */

nv_item.ssd_a.nam = 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 = NAM_index;
qw_equ( nv_item.ssd_b.ssd, CAVE_SSD_B);
auth_put_nv_item( NV_SSD_B_I, &nv_item );

/* Perform Initialization here if necessary */

MSG_MED("A-key updated", 0L, 0L, 0L);

return TRUE;

} /* CAVE_update_A_key */


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

FUNCTION CAVE_update_A_key_683

DESCRIPTION
  This function installs a new A-key in the phone generated using IS-683A.

DEPENDENCIES
  None.

RETURN VALUE
  Returns TRUE.

SIDE EFFECTS
  NV is updated: the new A-key is stored

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

boolean  CAVE_update_A_key_683
(
  qword new_A_key,
    /* A-key to be put into NV */

  byte NAM_index
    /* Which NAM is to be updated */
)
{
  nv_item_type nv_item;
    /* Item to hold values retrieved from NV */

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

qw_equ(CAVE_A_key, new_A_key);               /* Accept the new A-Key */

nv_item.a_key.nam = NAM_index;
qw_equ( nv_item.a_key.key, CAVE_A_key);
auth_put_nv_item( NV_A_KEY_I, &nv_item );

MSG_MED("IS 683-A A-key updated", 0L, 0L, 0L);

return TRUE;
} /* CAVE_update_A_key_683 */

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

FUNCTION CAVE_generate_SSD

DESCRIPTION
  This function generates new A and B values of Shared Secret Data.

DEPENDENCIES
  CAVE_init must be called before this function is called.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

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

void  CAVE_generate_SSD
(
  qword  rand_ssd
    /* The random input to the SSD generation process */
)

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

  qword  a_key;
    /* The version of A-Key to use for this computation. */

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

      /* Use the specified version of A-Key. */
qw_equ(a_key, a_key_temp_valid ? a_key_temp : CAVE_A_key );
      
      /* Initialize all CAVE variables for SSD Generation, as
         specified in "Common Cryptographic Algorithms", Section 2.2.1 */

  MSG_MED( "SSD rand_ssd %ld %ld", qw_hi(rand_ssd), qw_lo(rand_ssd), 0 );
  
CAVE_lfsr = qw_lo(rand_ssd) ^ qw_hi(a_key) ^ qw_lo(a_key);

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

                        /* Copy the A-key into mixing_reg */
for (R_index = 0; R_index <= 7; R_index++)
  {
  CAVE_mixing_reg[R_index] = QW_BYTE(a_key, 7 - R_index);
  }

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

                        /* Copy the random input into mixing_reg */
for (R_index = 9; R_index <= 11; R_index++)
  {
  CAVE_mixing_reg[R_index] = QW_BYTE(rand_ssd, 15 - 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 */

   /* Copy the mixing registers into the new SSD values, accounting
      for the reverse byte order of the mixing registers */
for (R_index = 0; R_index <= 7; R_index++)
  {
  /*lint -e545  B_PTR does work on qwords, even if lint is suspicious. */
  B_PTR(CAVE_new_SSD_A)[7 - R_index] = CAVE_mixing_reg[R_index    ];
  B_PTR(CAVE_new_SSD_B)[7 - R_index] = CAVE_mixing_reg[R_index + 8];
  /*lint -restore */
  }
} /* CAVE_generate_SSD */

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

FUNCTION CAVE_update_SSD

DESCRIPTION
  This function installs new A and B values of SSD into the phone.

DEPENDENCIES
  None.

RETURN VALUE
  Returns TRUE if the SSD is updated successfully, FALSE if not.

SIDE EFFECTS
  NV is updated: the new SSD is stored.

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

boolean CAVE_update_SSD(void)
{
  nv_item_type nv_item;
    /* Item to hold values retrieved from NV */

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

qw_equ(CAVE_SSD_A, CAVE_new_SSD_A);           /* Accept the new SSD values */
qw_equ(CAVE_SSD_B, CAVE_new_SSD_B);

⌨️ 快捷键说明

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