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

📄 xfm.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
字号:
/* * xfm.c * * Crypto transform implementation * * David A. McGrew * Cisco Systems, Inc. */#include "cryptoalg.h"#include "aes_cbc.h"#include "hmac.h"#include "crypto_kernel.h"   /* for crypto_get_random() */#define KEY_LEN     16#define ENC_KEY_LEN 16#define MAC_KEY_LEN 16#define IV_LEN      16#define TAG_LEN     12#define MAX_EXPAND  27err_status_taes_128_cbc_hmac_sha1_96_func(void *key,            			      void *clear,          			      unsigned clear_len,       			      void *iv,             			      void *opaque,         			      unsigned *opaque_len, 			      void *auth_tag) {  aes_cbc_ctx_t aes_ctx;  hmac_ctx_t hmac_ctx;  unsigned char enc_key[ENC_KEY_LEN];  unsigned char mac_key[MAC_KEY_LEN];  err_status_t status;  /* check if we're doing authentication only */  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {            /* perform authentication only */  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {        /*     * bad parameter - we expect either all three pointers to be NULL,     * or none of those pointers to be NULL      */    return err_status_fail;  } else {    /* derive encryption and authentication keys from the input key */    status = hmac_init(&hmac_ctx, key, KEY_LEN);    if (status) return status;    status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);    if (status) return status;    status = hmac_init(&hmac_ctx, key, KEY_LEN);    if (status) return status;    status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);    if (status) return status;    /* perform encryption and authentication */    /* set aes key */    status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);    if (status) return status;    /* set iv */    status = crypto_get_random(iv, IV_LEN);      if (status) return status;     status = aes_cbc_set_iv(&aes_ctx, iv);        /* encrypt the opaque data  */    status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);    if (status) return status;    /* authenticate clear and opaque data */    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);    if (status) return status;    status = hmac_start(&hmac_ctx);    if (status) return status;    status = hmac_update(&hmac_ctx, clear, clear_len);    if (status) return status;    status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);    if (status) return status;  }  return err_status_ok;}err_status_taes_128_cbc_hmac_sha1_96_inv(void *key,            			     void *clear,          			     unsigned clear_len,       			     void *iv,             			     void *opaque,         			     unsigned *opaque_len, 			     void *auth_tag) {  aes_cbc_ctx_t aes_ctx;  hmac_ctx_t hmac_ctx;  unsigned char enc_key[ENC_KEY_LEN];  unsigned char mac_key[MAC_KEY_LEN];  unsigned char tmp_tag[TAG_LEN];  unsigned char *tag = auth_tag;  err_status_t status;  int i;    /* check if we're doing authentication only */  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {            /* perform authentication only */  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {        /*     * bad parameter - we expect either all three pointers to be NULL,     * or none of those pointers to be NULL      */    return err_status_fail;  } else {    /* derive encryption and authentication keys from the input key */    status = hmac_init(&hmac_ctx, key, KEY_LEN);    if (status) return status;    status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);    if (status) return status;    status = hmac_init(&hmac_ctx, key, KEY_LEN);    if (status) return status;    status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);    if (status) return status;    /* perform encryption and authentication */    /* set aes key */    status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);    if (status) return status;    /* set iv */    status = rand_source_get_octet_string(iv, IV_LEN);      if (status) return status;     status = aes_cbc_set_iv(&aes_ctx, iv);        /* encrypt the opaque data  */    status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len);    if (status) return status;    /* authenticate clear and opaque data */    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);    if (status) return status;    status = hmac_start(&hmac_ctx);    if (status) return status;    status = hmac_update(&hmac_ctx, clear, clear_len);    if (status) return status;    status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag);    if (status) return status;    /* compare the computed tag with the one provided as input */    for (i=0; i < TAG_LEN; i++)      if (tmp_tag[i] != tag[i]) 	return err_status_auth_fail;   }  return err_status_ok;}#define ENC 1#define DEBUG 0err_status_taes_128_cbc_hmac_sha1_96_enc(void *key,            			     const void *clear,          			     unsigned clear_len,       			     void *iv,             			     void *opaque,         			     unsigned *opaque_len) {  aes_cbc_ctx_t aes_ctx;  hmac_ctx_t hmac_ctx;  unsigned char enc_key[ENC_KEY_LEN];  unsigned char mac_key[MAC_KEY_LEN];  unsigned char *auth_tag;  err_status_t status;  /* check if we're doing authentication only */  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {            /* perform authentication only */  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {        /*     * bad parameter - we expect either all three pointers to be NULL,     * or none of those pointers to be NULL      */    return err_status_fail;  } else {#if DEBUG    printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));#endif    /* derive encryption and authentication keys from the input key */    status = hmac_init(&hmac_ctx, key, KEY_LEN);    if (status) return status;    status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);    if (status) return status;    status = hmac_init(&hmac_ctx, key, KEY_LEN);    if (status) return status;    status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);    if (status) return status;    /* perform encryption and authentication */    /* set aes key */    status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);    if (status) return status;    /* set iv */    status = rand_source_get_octet_string(iv, IV_LEN);      if (status) return status;     status = aes_cbc_set_iv(&aes_ctx, iv);    if (status) return status;#if DEBUG    printf("plaintext len:  %d\n", *opaque_len);    printf("iv:         %s\n", octet_string_hex_string(iv, IV_LEN));    printf("plaintext:  %s\n", octet_string_hex_string(opaque, *opaque_len));#endif#if ENC        /* encrypt the opaque data  */    status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);    if (status) return status;#endif#if DEBUG    printf("ciphertext len: %d\n", *opaque_len);    printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));#endif    /*     * authenticate clear and opaque data, then write the     * authentication tag to the location immediately following the     * ciphertext     */    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);    if (status) return status;    status = hmac_start(&hmac_ctx);    if (status) return status;    status = hmac_update(&hmac_ctx, clear, clear_len);    if (status) return status;#if DEBUG    printf("hmac input: %s\n", 	   octet_string_hex_string(clear, clear_len));#endif    auth_tag = (unsigned char *)opaque;    auth_tag += *opaque_len;        status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);    if (status) return status;#if DEBUG    printf("hmac input: %s\n", 	   octet_string_hex_string(opaque, *opaque_len));#endif    /* bump up the opaque_len to reflect the authentication tag */    *opaque_len += TAG_LEN;#if DEBUG    printf("prot data len:  %d\n", *opaque_len);    printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));#endif  }  return err_status_ok;}err_status_taes_128_cbc_hmac_sha1_96_dec(void *key,            			     const void *clear,          			     unsigned clear_len,       			     void *iv,             			     void *opaque,         			     unsigned *opaque_len) {  aes_cbc_ctx_t aes_ctx;  hmac_ctx_t hmac_ctx;  unsigned char enc_key[ENC_KEY_LEN];  unsigned char mac_key[MAC_KEY_LEN];  unsigned char tmp_tag[TAG_LEN];  unsigned char *auth_tag;  unsigned ciphertext_len;  err_status_t status;  int i;    /* check if we're doing authentication only */  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {            /* perform authentication only */  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {        /*     * bad parameter - we expect either all three pointers to be NULL,     * or none of those pointers to be NULL      */    return err_status_fail;  } else {#if DEBUG    printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));#endif    /* derive encryption and authentication keys from the input key */    status = hmac_init(&hmac_ctx, key, KEY_LEN);    if (status) return status;    status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);    if (status) return status;    status = hmac_init(&hmac_ctx, key, KEY_LEN);    if (status) return status;    status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);    if (status) return status;#if DEBUG    printf("prot data len:  %d\n", *opaque_len);    printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));#endif    /*      * set the protected data length to that of the ciphertext, by     * subtracting out the length of the authentication tag      */    ciphertext_len = *opaque_len - TAG_LEN;#if DEBUG    printf("ciphertext len: %d\n", ciphertext_len);#endif        /* verify the authentication tag */    /*      * compute the authentication tag for the clear and opaque data,     * and write it to a temporary location     */    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);    if (status) return status;    status = hmac_start(&hmac_ctx);    if (status) return status;    status = hmac_update(&hmac_ctx, clear, clear_len);    if (status) return status;#if DEBUG    printf("hmac input: %s\n", 	   octet_string_hex_string(clear, clear_len));#endif    status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag);    if (status) return status;#if DEBUG    printf("hmac input: %s\n", 	   octet_string_hex_string(opaque, ciphertext_len));#endif    /*      * compare the computed tag with the one provided as input (which     * immediately follows the ciphertext)     */    auth_tag = (unsigned char *)opaque;    auth_tag += ciphertext_len;  #if DEBUG    printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN));    printf("tmp_tag:  %s\n", octet_string_hex_string(tmp_tag, TAG_LEN));#endif    for (i=0; i < TAG_LEN; i++) {      if (tmp_tag[i] != auth_tag[i]) 	return err_status_auth_fail;     }    /* bump down the opaque_len to reflect the authentication tag */    *opaque_len -= TAG_LEN;    /* decrypt the confidential data */    status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);    if (status) return status;    status = aes_cbc_set_iv(&aes_ctx, iv);    if (status) return status;#if DEBUG    printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));    printf("iv:         %s\n", octet_string_hex_string(iv, IV_LEN));#endif#if ENC    status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len);    if (status) return status;#endif#if DEBUG    printf("plaintext len:  %d\n", ciphertext_len);    printf("plaintext:  %s\n", 	   octet_string_hex_string(opaque, ciphertext_len));#endif    /* indicate the length of the plaintext  */    *opaque_len = ciphertext_len;  }  return err_status_ok;}cryptoalg_ctx_t cryptoalg_ctx = {  aes_128_cbc_hmac_sha1_96_enc,  aes_128_cbc_hmac_sha1_96_dec,  KEY_LEN,  IV_LEN,  TAG_LEN,  MAX_EXPAND,};cryptoalg_t cryptoalg = &cryptoalg_ctx;#define NULL_TAG_LEN 12err_status_tnull_enc(void *key,            	 const void *clear,          	 unsigned clear_len,       	 void *iv,             	 void *opaque,         	 unsigned *opaque_len) {  int i;  unsigned char *auth_tag;  unsigned char *init_vec = iv;  /* check if we're doing authentication only */  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {            /* perform authentication only */  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {        /*     * bad parameter - we expect either all three pointers to be NULL,     * or none of those pointers to be NULL      */    return err_status_fail;  } else {#if DEBUG    printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));    printf("NULL_TAG_LEN:  %d\n", NULL_TAG_LEN);    printf("plaintext len:  %d\n", *opaque_len);#endif    for (i=0; i < IV_LEN; i++)      init_vec[i] = i + (i * 16);#if DEBUG    printf("iv:                %s\n", 	   octet_string_hex_string(iv, IV_LEN));    printf("plaintext:         %s\n", 	   octet_string_hex_string(opaque, *opaque_len));#endif    auth_tag = opaque;    auth_tag += *opaque_len;    for (i=0; i < NULL_TAG_LEN; i++)      auth_tag[i] = i + (i * 16);    *opaque_len += NULL_TAG_LEN;#if DEBUG    printf("protected data len: %d\n", *opaque_len);    printf("protected data:    %s\n", 	   octet_string_hex_string(opaque, *opaque_len));#endif  }  return err_status_ok;}err_status_tnull_dec(void *key,            	 const void *clear,          	 unsigned clear_len,       	 void *iv,             	 void *opaque,         	 unsigned *opaque_len) {  unsigned char *auth_tag;    /* check if we're doing authentication only */  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {            /* perform authentication only */  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {        /*     * bad parameter - we expect either all three pointers to be NULL,     * or none of those pointers to be NULL      */    return err_status_fail;  } else {#if DEBUG    printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));    printf("protected data len: %d\n", *opaque_len);    printf("protected data:    %s\n", 	   octet_string_hex_string(opaque, *opaque_len));#endif    auth_tag = opaque;    auth_tag += (*opaque_len - NULL_TAG_LEN);#if DEBUG    printf("iv:         %s\n", octet_string_hex_string(iv, IV_LEN));#endif    *opaque_len -= NULL_TAG_LEN;#if DEBUG    printf("plaintext len:  %d\n", *opaque_len);    printf("plaintext:  %s\n", 	   octet_string_hex_string(opaque, *opaque_len));#endif  }  return err_status_ok;}cryptoalg_ctx_t null_cryptoalg_ctx = {  null_enc,  null_dec,  KEY_LEN,  IV_LEN,  NULL_TAG_LEN,  MAX_EXPAND,};cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx;intcryptoalg_get_id(cryptoalg_t c) {  if (c == cryptoalg)    return 1;  return 0;}cryptoalg_t cryptoalg_find_by_id(int id) {  switch(id) {  case 1:    return cryptoalg;  default:    break;  }  return 0;}

⌨️ 快捷键说明

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