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

📄 crypto.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (C) Ericsson Mobile Communications AB, 2000.
 * Licensed to AU-System AB.
 * All rights reserved.
 *
 * This software is covered by the license agreement between
 * the end user and AU-System AB, and may be used and copied
 * only in accordance with the terms of the said agreement.
 *
 * Neither Ericsson Mobile Communications AB nor AU-System AB
 * assumes any responsibility or liability for any errors or inaccuracies in
 * this software, or any consequential, incidental or indirect damage arising
 * out of the use of the Generic WAP Client software.
 */
/*
 * Crypto.c
 *
 * Created by Anders Edenbrandt, Fri Jun 02 07:59:31 2000.
 *
 * Revision history:
 *
 */
#include "wtlsdef.h"
#ifdef LOG_EXTERNAL
#include "aapiclnt.h"
#include "logcodes.h"
#endif

/* Information below is from WTLS spec. Appendix A */

#define NUM_CIPHER_ALGS  12

static const struct {
  UINT8 bulk_cipher_alg;
  UINT8 is_exportable;
  UINT8 type;
  UINT8 key_material_length;
  UINT8 key_size;
  UINT8 iv_size;
  UINT8 block_size;
} bulk_cipher_alg_info[NUM_CIPHER_ALGS] = {
  {CIPHER_NULL, TRUE, CIPHER_TYPE_STREAM, 0, 0, 0, 0},
  {CIPHER_RC5_CBC_40, TRUE, CIPHER_TYPE_BLOCK, 5, 16, 8, 8},
  {CIPHER_RC5_CBC_56, TRUE, CIPHER_TYPE_BLOCK, 7, 16, 8, 8},
  {CIPHER_RC5_CBC, FALSE, CIPHER_TYPE_BLOCK, 16, 16, 8, 8},
  {CIPHER_DES_CBC_40, TRUE, CIPHER_TYPE_BLOCK, 5, 8, 8, 8},
  {CIPHER_DES_CBC, FALSE, CIPHER_TYPE_BLOCK, 8, 8, 8, 8},
  {CIPHER_3DES_CBC_EDE, FALSE, CIPHER_TYPE_BLOCK, 24, 24, 8, 8},
  {CIPHER_IDEA_CBC_40, TRUE, CIPHER_TYPE_BLOCK, 5, 16, 8, 8},
  {CIPHER_IDEA_CBC_56, TRUE, CIPHER_TYPE_BLOCK, 7, 16, 8, 8},
  {CIPHER_IDEA_CBC, FALSE, CIPHER_TYPE_BLOCK, 16, 16, 8, 8},
  {CIPHER_RC5_CBC_64, TRUE, CIPHER_TYPE_BLOCK, 8, 16, 8, 8},
  {CIPHER_IDEA_CBC_64, TRUE, CIPHER_TYPE_BLOCK, 8, 16, 8, 8}
};

#define NUM_MAC_ALGS 8

static const struct {
  UINT8 mac_alg;
  UINT8 mac_key_size;
  UINT8 mac_size;
  UINT8 full_mac_size;
  UINT8 mac_block_size;
} MAC_alg_info[NUM_MAC_ALGS] = {
  {MAC_SHA_0, 0, 0, 20, 64},
  {MAC_SHA_40, 20, 5, 20, 64},
  {MAC_SHA_80, 20, 10, 20, 64},
  {MAC_SHA, 20, 20, 20, 64},
  {MAC_SHA_XOR_40, 0, 5, 20, 5},
  {MAC_MD5_40, 16, 5, 16, 64},
  {MAC_MD5_80, 16, 10, 16, 64},
  {MAC_MD5, 16, 16, 16, 64}
};


/*
 * For a given WTLS MAC algorithm, return the underlying
 * secure hash algorithm.
 */
HashAlgorithm
wtls_crypto_MAC_to_hash_alg (wtls_MAC_algorithm alg)
{
  switch (alg) {
  case MAC_SHA_0:
  case MAC_SHA_40:
  case MAC_SHA_80:
  case MAC_SHA:
  case MAC_SHA_XOR_40:
    return HASH_SHA;

  case MAC_MD5_40:
  case MAC_MD5_80:
  case MAC_MD5:
    return HASH_MD5;

  default:
    return 0;
  }
}

/*
 * Initialize a cryptographic object according to the given parameters.
 */
INT16
wtls_crypto_init (wtls_crypto_t *cobj,
                  BulkCipherAlgorithm bulk_cipher_alg,
                  wtls_MAC_algorithm mac_alg,
                  UINT8 compression_alg)
{
  /* First, the bulk encryption algorithm. */
  if (bulk_cipher_alg >= NUM_CIPHER_ALGS) {
    wtls_err_set (ERR_INTERNAL, ERR_PROGRAMMING_ERROR,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }
  /* Consistency check */
  if (bulk_cipher_alg !=
      bulk_cipher_alg_info[bulk_cipher_alg].bulk_cipher_alg) {
    wtls_err_set (ERR_INTERNAL, ERR_PROGRAMMING_ERROR,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }
  cobj->bulk_cipher_alg = bulk_cipher_alg;
  cobj->is_exportable = bulk_cipher_alg_info[bulk_cipher_alg].is_exportable;
  cobj->type = bulk_cipher_alg_info[bulk_cipher_alg].type;
  cobj->key_material_length =
    bulk_cipher_alg_info[bulk_cipher_alg].key_material_length;
  cobj->key_size = bulk_cipher_alg_info[bulk_cipher_alg].key_size;
  cobj->iv_size = bulk_cipher_alg_info[bulk_cipher_alg].iv_size;
  cobj->block_size = bulk_cipher_alg_info[bulk_cipher_alg].block_size;

  /* Next, the cryptographic hash algorithm. */
  if (mac_alg >= NUM_MAC_ALGS) {
    wtls_err_set (ERR_INTERNAL, ERR_PROGRAMMING_ERROR,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }
  /* Consistency check */
  if (mac_alg != MAC_alg_info[mac_alg].mac_alg) {
    wtls_err_set (ERR_INTERNAL, ERR_PROGRAMMING_ERROR,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }
  cobj->mac_alg = mac_alg;
  cobj->mac_key_size = MAC_alg_info[mac_alg].mac_key_size;
  cobj->mac_size = MAC_alg_info[mac_alg].mac_size;
  cobj->full_mac_size = MAC_alg_info[mac_alg].full_mac_size;
  cobj->mac_block_size = MAC_alg_info[mac_alg].mac_block_size;
  cobj->hash_handle = NULL;
  cobj->hash_alg = wtls_crypto_MAC_to_hash_alg (mac_alg);

  /* Finally, the compression algorithm. */
  if (compression_alg != COMPRESS_NULL) {
    wtls_err_set (ERR_INTERNAL, ERR_PROGRAMMING_ERROR,
                  1, ALERT_LEVEL_FATAL, ALERT_DESC_INTERNAL_ERROR);
    return -1;
  }
  cobj->compression_alg = COMPRESS_NULL;

  return RET_OK;
}

/*
 * Bulk encryption.
 */
INT16
wtls_crypto_encrypt (wtls_crypto_t *cobj,
                     BYTE *key, BYTE *iv,
                     BYTE *buf, UINT16 buflen,
                     BYTE *outbuf)
{
  KeyObject keyobj;
  INT16     r;

  keyobj.key = key;
  keyobj.keyLen = cobj->key_size;
  keyobj.iv = iv;
  keyobj.ivLen = cobj->iv_size;

#ifdef LOG_EXTERNAL
  CLNTa_log (0, log_wtls_CRYPTa_encrypt, "WTLS: calling CRYPTa_encrypt");
#endif
  if ((r = CRYPTa_encrypt (cobj->bulk_cipher_alg, keyobj,
                           buf, buflen, outbuf)) != CRV_OK) {
    wtls_err_set (ERR_CRYPTLIB, ERR_ENCRYPT,
                  1, ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
#ifdef LOG_EXTERNAL
    CLNTa_log (0, log_wtls_CRYPTa_encrypt,
               "WTLS: error return from CRYPTa_encrypt: %d\n", r);
#endif
    return -1;
  }

  return RET_OK;
}

/*
 * Bulk decryption.
 */
INT16
wtls_crypto_decrypt (wtls_crypto_t *cobj,
                     BYTE *key, BYTE *iv,
                     BYTE *buf, UINT16 buflen,
                     BYTE *outbuf)
{
  KeyObject keyobj;
  INT16     r;

  keyobj.key = key;
  keyobj.keyLen = cobj->key_size;
  keyobj.iv = iv;
  keyobj.ivLen = cobj->iv_size;

#ifdef LOG_EXTERNAL
  CLNTa_log (0, log_wtls_CRYPTa_decrypt, "WTLS: calling CRYPTa_decrypt");
#endif
  if ((r = CRYPTa_decrypt (cobj->bulk_cipher_alg,
                           keyobj, buf, buflen,
                           outbuf)) != CRV_OK) {
    wtls_err_set (ERR_CRYPTLIB, ERR_DECRYPT,
                  1, ALERT_LEVEL_WARNING, ALERT_DESC_DECRYPTION_FAILED);
#ifdef LOG_EXTERNAL
    CLNTa_log (0, log_wtls_CRYPTa_decrypt,
               "WTLS: error return from CRYPTa_decrypt: %d\n", r);
#endif
    return -1;
  }

  return RET_OK;
}

/*
 * Secure hash algorithms.
 */
INT16
wtls_crypto_hash (wtls_crypto_t *cobj, BYTE *buf, UINT16 buflen, BYTE *digest)
{
  INT16  r;

#ifdef LOG_EXTERNAL
  CLNTa_log (0, log_wtls_CRYPTa_hash, "WTLS: calling CRYPTa_hash");
#endif
  if ((r = CRYPTa_hash (cobj->hash_alg,
                        buf, buflen, digest)) != CRV_OK) {
    wtls_err_set (ERR_CRYPTLIB, ERR_HASH,
                  1, ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
#ifdef LOG_EXTERNAL
    CLNTa_log (0, log_wtls_CRYPTa_hash,
               "WTLS: error return from CRYPTa_hash: %d\n", r);
#endif
    return -1;
  }

  return RET_OK;
}

INT16
wtls_crypto_hash_init (wtls_crypto_t *cobj)
{
  INT16 r;

#ifdef LOG_EXTERNAL
  CLNTa_log (0, log_wtls_CRYPTa_hashInit, "WTLS: calling CRYPTa_hashInit");
#endif
  if ((r = CRYPTa_hashInit (cobj->hash_alg,
                            &(cobj->hash_handle))) != CRV_OK) {
    wtls_err_set (ERR_CRYPTLIB, ERR_HASH_INIT,
                  1, ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
#ifdef LOG_EXTERNAL
    CLNTa_log (0, log_wtls_CRYPTa_hashInit,
               "WTLS: error return from CRYPTa_hashInit: %d\n", r);
#endif
    return -1;
  }

  return RET_OK;
}

INT16
wtls_crypto_hash_update (wtls_crypto_t *cobj, BYTE *buf, UINT16 buflen)
{
  INT16 r;

#ifdef LOG_EXTERNAL
  CLNTa_log (0, log_wtls_CRYPTa_hashUpdate, "WTLS: calling CRYPTa_hashUpdate");
#endif
  if ((r = CRYPTa_hashUpdate (cobj->hash_handle, buf, buflen)) != CRV_OK) {
    wtls_err_set (ERR_CRYPTLIB, ERR_HASH_UPDATE,
                  1, ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
#ifdef LOG_EXTERNAL
    CLNTa_log (0, log_wtls_CRYPTa_hashUpdate,
               "WTLS: error return from CRYPTa_hashUpdate: %d\n", r);
#endif
    return -1;
  }

  return RET_OK;
}

INT16
wtls_crypto_hash_final (wtls_crypto_t *cobj, BYTE *digest)
{
  INT16  r;

#ifdef LOG_EXTERNAL
  CLNTa_log (0, log_wtls_CRYPTa_hashFinal, "WTLS: calling CRYPTa_hashFinal");
#endif
  if ((r = CRYPTa_hashFinal (cobj->hash_handle, digest)) != CRV_OK) {
    wtls_err_set (ERR_CRYPTLIB, ERR_HASH_FINAL,
                  1, ALERT_LEVEL_CRITICAL, ALERT_DESC_INTERNAL_ERROR);
#ifdef LOG_EXTERNAL
    CLNTa_log (0, log_wtls_CRYPTa_hashFinal,
               "WTLS: error return from CRYPTa_hashFinal: %d\n", r);
#endif
    return -1;
  }

  return RET_OK;
}


#if 0
/*
 * The NULL compression algorithm, which does not do any compression.
 * The WTLS spec requires that we support the NULL compression algorithm,
 * and, in fact does not presently define any alternative method.
 */
INT16
wtls_crypto_compress (wtls_crypto_t *cobj,
                      BYTE *buf, UINT16 buflen,
                      BYTE *outbuf, UINT16 *outbuflen)
{

⌨️ 快捷键说明

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