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

📄 crypto.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
  cobj = cobj;

  if (outbuf == NULL) {
    *outbuflen = buflen;
    return RET_OK;
  }
  if (*outbuflen < buflen) {
    *outbuflen = buflen;
    return -1;
  }
  *outbuflen = buflen;
  B_COPYSTRINGN (outbuf, buf, buflen);

  return RET_OK;
}

INT16
wtls_crypto_decompress (wtls_crypto_t *cobj,
                        BYTE *buf, UINT16 buflen,
                        BYTE *outbuf, UINT16 *outbuflen)
{
  cobj = cobj;

  if (outbuf == NULL) {
    *outbuflen = buflen;
    return RET_OK;
  }
  if (*outbuflen < buflen) {
    *outbuflen = buflen;
    return -1;
  }
  *outbuflen = buflen;
  B_COPYSTRINGN (outbuf, buf, buflen);

  return RET_OK;
}
#endif

INT16
wtls_crypto_HMAC_init (wtls_crypto_t *cobj, BYTE *key, UINT16 keylen)
{
  BYTE   buf1[MAX_HASH_BLOCK_SIZE];
  UINT16 i = 0;

  if (keylen > cobj->mac_block_size) {
    wtls_err_set (ERR_CRYPTLIB, ERR_HASH_KEY_TOO_LONG,
                  1, ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }

  /* Step 0: Copy the key material */
  /* Step 1: Append zeros to a length of B bytes */
  /* Step 2: XOR with ipad (0x36) */
  for (i = 0; i < keylen; i++) {
    buf1[i] = key[i] ^ 0x36;
  }
  for (i = keylen; i < cobj->mac_block_size; i++) {
    buf1[i] = 0x36;
  }

  /* Step 3: Append the data */
  /* Step 4: Apply H to the data generated in step 3. */
  if ((wtls_crypto_hash_init (cobj) < 0) ||
      (wtls_crypto_hash_update (cobj, buf1, cobj->mac_block_size) < 0)) {
    return -1;
  }

  return RET_OK;
}

INT16
wtls_crypto_HMAC_update (wtls_crypto_t *cobj, BYTE *data, UINT16 datalen)
{
  if (wtls_crypto_hash_update (cobj, data, datalen) < 0) {
    return -1;
  }

  return RET_OK;
}

INT16
wtls_crypto_HMAC_final (wtls_crypto_t *cobj,
                        BYTE *key, UINT16 keylen, BYTE *result)
{
  BYTE  buf1[MAX_HASH_BLOCK_SIZE];
  BYTE  md[MAX_HASH_MAC_SIZE];
  INT16 i;

  if (wtls_crypto_hash_final (cobj, md) < 0) {
    return -1;
  }

  /* Step 5: XOR the byte string computed in step 1 with opad (0x5c) */
  for (i = 0; i < keylen; i++) {
    buf1[i] = key[i] ^ 0x5c;
  }
  for (i = keylen; i < cobj->mac_block_size; i++) {
    buf1[i] = 0x5c;
  }

  /* Step 6: Append the result from step 4 to the string from step 5 */
  /* Step 7: Apply H to the data generated in step 6 */
  if ((wtls_crypto_hash_init (cobj) < 0) ||
      (wtls_crypto_hash_update (cobj, buf1, cobj->mac_block_size) < 0) ||
      (wtls_crypto_hash_update (cobj, md, cobj->full_mac_size) < 0) ||
      (wtls_crypto_hash_final (cobj, result) < 0)) {
    return -1;
  }

  return RET_OK;
}


/*
 * Compute the Message Authentication Code as described in sections 9.2.3.2
 * and 11.3.1 of the WTLS specification.
 * The result is placed at the location indicated by 'mac'.
 */
INT16
wtls_crypto_MAC (wtls_crypto_t *cobj, BYTE *mac_secret,
                 BYTE *buf, UINT16 buflen,
                 UINT16 seqnum, UINT8 rec_type,
                 BYTE *mac)
{
  BYTE   tmpbuf[5];

  /* Here we use WTLS spec section 9.2.3.2.
   * Concatenate: seqnum + rec_type + buflen + data */
  tmpbuf[0] = (seqnum >> 8) & 0xff;
  tmpbuf[1] = seqnum & 0xff;
  tmpbuf[2] = rec_type;
  tmpbuf[3] = (buflen >> 8) & 0xff;
  tmpbuf[4] = buflen & 0xff;

  if ((wtls_crypto_HMAC_init (cobj, mac_secret, cobj->mac_key_size) < 0) ||
      (wtls_crypto_HMAC_update (cobj, tmpbuf, 5) < 0) ||
      (wtls_crypto_HMAC_update (cobj, buf, buflen) < 0) ||
      (wtls_crypto_HMAC_final (cobj, mac_secret,
                               cobj->mac_key_size, mac) < 0)) {
    return -1;
  }

  return RET_OK;
}


/*
 * Return the length of the key block to be generated as part
 * of key generation.
 */
static UINT16
wtls_crypto_key_block_size (wtls_crypto_t *cobj)
{
  return  cobj->mac_key_size + cobj->key_material_length + cobj->iv_size;
}

/*
 * Refresh the read keys for this connection state, using the given
 * label and sequence number.
 */
INT16
wtls_crypto_key_refresh1 (void *connptr, SDL_Natural state)
{
  wtls_connection_t     *conn = (wtls_connection_t *)connptr;
  wtls_connection_state *cstate;
  CHAR                  *label;
  UINT16                seqnum;
  UINT16                key_block_size;
  BYTE                  p[34];
  BYTE                  tmplabel[20];

  if (state == CONSTATE_READ) {
    cstate = &(conn->read);
    label = "server";
  }
  else {
    cstate = &(conn->write);
    label = "client";
  }
  seqnum = cstate->last_refresh;
  key_block_size = wtls_crypto_key_block_size (&(cstate->cobj));

  /* Concatenate: seqnum + ServerHello.random + ClientHello.random */
  p[0] = (seqnum >> 8) & 0xff;
  p[1] = seqnum & 0xff;
  B_COPYSTRINGN (p + 2, cstate->server_hello_random, 16);
  B_COPYSTRINGN (p + 18, cstate->client_hello_random, 16);

  sprintf (tmplabel, "%s expansion", label);
#ifdef LOG_EXTERNAL
  CLNTa_log (0, log_wtls_CRYPTa_PRF, "WTLS: calling CRYPTa_PRF");
#endif
  CRYPTa_PRF ((UINT16)conn->rec_proc,
              cstate->cobj.hash_alg,
              cstate->master_secret_id, NULL, 0,
              tmplabel, p, 34, key_block_size);

  return RET_OK;
}

INT16
wtls_crypto_key_refresh2 (void *connptr, SDL_Natural state,
                          void *buf, SDL_Natural buflen)
{
  wtls_connection_t     *conn = (wtls_connection_t *)connptr;
  wtls_connection_state *cstate;

  buflen = buflen;

  if (state == CONSTATE_READ) {
    cstate = &(conn->read);
  }
  else {
    cstate = &(conn->write);
  }

  B_COPYSTRINGN (cstate->mac_secret, buf, cstate->cobj.mac_key_size);
  B_COPYSTRINGN (cstate->encryption_key,
                 (BYTE *)buf + cstate->cobj.mac_key_size,
                 cstate->cobj.key_material_length);
  B_COPYSTRINGN (cstate->iv, (BYTE *)buf + cstate->cobj.mac_key_size +
                 cstate->cobj.key_material_length, cstate->cobj.iv_size);
  DEALLOC (&buf);

  if (cstate->cobj.is_exportable) {
    return RET_EXPORTABLE;
  }
  else {
    return RET_OK;
  }
}

INT16
wtls_crypto_key_refresh3 (void *connptr, SDL_Natural state)
{
  wtls_connection_t     *conn = (wtls_connection_t *)connptr;
  wtls_connection_state *cstate;
  CHAR                  *label;
  BYTE                  p[34];
  BYTE                  tmplabel[20];

  if (state == CONSTATE_READ) {
    cstate = &(conn->read);
    label = "server";
  }
  else {
    cstate = &(conn->write);
    label = "client";
  }

  /* Exportable algorithms have a shorter keyMaterialLength than keyLength,
   * and hence need a further expansion to bring the key length up
   * to the required length. */
  B_COPYSTRINGN (p, cstate->client_hello_random, 16);
  B_COPYSTRINGN (p + 16, cstate->server_hello_random, 16);
  sprintf (tmplabel, "%s write key", label);
#ifdef LOG_EXTERNAL
  CLNTa_log (0, log_wtls_CRYPTa_PRF, "WTLS: calling CRYPTa_PRF");
#endif
  CRYPTa_PRF ((UINT16)conn->rec_proc,
              cstate->cobj.hash_alg,
              0, cstate->encryption_key,
              cstate->cobj.key_material_length,
              tmplabel, p, 32, cstate->cobj.key_size);

  return RET_OK;
}

INT16
wtls_crypto_key_refresh4 (void *connptr, SDL_Natural state, void *buf,
                          SDL_Natural buflen)
{
  wtls_connection_t     *conn = (wtls_connection_t *)connptr;
  wtls_connection_state *cstate;
  CHAR                  *label;
  UINT16                seqnum;
  BYTE                  p[34];
  BYTE                  tmplabel[20];

  buflen = buflen;

  if (state == CONSTATE_READ) {
    cstate = &(conn->read);
    label = "server";
  }
  else {
    cstate = &(conn->write);
    label = "client";
  }
  seqnum = cstate->last_refresh;

  B_COPYSTRINGN (cstate->encryption_key, buf, cstate->cobj.key_size);
  DEALLOC (&buf);

  p[0] = (seqnum >> 8) & 0xff;
  p[1] = seqnum & 0xff;
  B_COPYSTRINGN (p + 2, cstate->client_hello_random, 16);
  B_COPYSTRINGN (p + 18, cstate->server_hello_random, 16);
  sprintf (tmplabel, "%s write IV", label);
#ifdef LOG_EXTERNAL
  CLNTa_log (0, log_wtls_CRYPTa_PRF, "WTLS: calling CRYPTa_PRF");
#endif
  CRYPTa_PRF ((UINT16)conn->rec_proc,
              cstate->cobj.hash_alg,
              0, "", 0, tmplabel,
              p, 34, cstate->cobj.iv_size);

  return RET_OK;
}

INT16
wtls_crypto_key_refresh5 (void *connptr, SDL_Natural state,
                          void *buf, SDL_Natural buflen)
{
  wtls_connection_t     *conn = (wtls_connection_t *)connptr;
  wtls_connection_state *cstate;

  buflen = buflen;

  if (state == CONSTATE_READ) {
    cstate = &(conn->read);
  }
  else {
    cstate = &(conn->write);
  }
  B_COPYSTRINGN (cstate->iv, buf, cstate->cobj.iv_size);
  DEALLOC (&buf);

  return RET_OK;
}

⌨️ 快捷键说明

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