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

📄 modetest.c

📁 加密认证联合模式的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 ---------------------------------------------------------------------------
 Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.

 LICENSE TERMS

 The free distribution and use of this software in both source and binary
 form is allowed (with or without changes) provided that:

   1. distributions of this source code include the above copyright
      notice, this list of conditions and the following disclaimer;

   2. distributions in binary form include the above copyright
      notice, this list of conditions and the following disclaimer
      in the documentation and/or other associated materials;

   3. the copyright holder's name is not used to endorse products
      built using this software without specific written permission.

 ALTERNATIVELY, provided that this notice is retained in full, this product
 may be distributed under the terms of the GNU General Public License (GPL),
 in which case the provisions of the GPL apply INSTEAD OF those given above.

 DISCLAIMER

 This software is provided 'as is' with no explicit or implied warranties
 in respect of its properties, including, but not limited to, correctness
 and/or fitness for purpose.
 ---------------------------------------------------------------------------
 Issue Date: 13/06/2006
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#if defined( DUAL_CORE ) && defined( _WIN32 )
#include <windows.h>
#endif

#include "rdtsc.h"

#define cstr_cmp _strnicmp

enum des_type { KEY =  0, NCE, HDR, PTX, CTX, TAG,      /* sequence values      */
                VEC = 16, END, NUL, ERR, RPT, REM };    /* non-sequence values  */

/*  Input sequence designators are listed first with the most slowly
    varying values earlier in the list. Then output values are listed,
    followed by other values such as commands and aliases (e.g. IV is
    an alias for NCE).
*/
char *des_name[] =      { "KEY ", "NCE ", "HDR ", "PTX ", "CTX ", "TAG ", "IV  ", "VEC ", "END ", "RPT ", "REM " };
enum des_type des_m[] = {  KEY  ,  NCE  ,  HDR  ,  PTX  ,  CTX  ,  TAG  ,  NCE  ,  VEC  ,  END  ,  RPT  ,  REM   };

char*   in_dir  = "testvals/";
char*   out_dir = "outvals/";

typedef int  ret_type;
typedef ret_type t_init_and_key(const unsigned char*, unsigned long, void*);
typedef ret_type t_init_message(const unsigned char*, unsigned long, void*);
typedef ret_type t_auth_header (const unsigned char*, unsigned long, void*);
typedef ret_type t_auth_data   (const unsigned char*, unsigned long, void*);
typedef ret_type t_crypt_data  (unsigned char*, unsigned long, void*);
typedef ret_type t_compute_tag (unsigned char*, unsigned long, void*);
typedef ret_type t_encrypt     (unsigned char*, unsigned long, void*);
typedef ret_type t_decrypt     (unsigned char*, unsigned long, void*);
typedef ret_type t_encrypt_message(
            const unsigned char*, unsigned long,
            const unsigned char*, unsigned long,
            unsigned char*, unsigned long,
            unsigned char*, unsigned long,
            void*);
typedef ret_type t_decrypt_message(
            const unsigned char*, unsigned long,
            const unsigned char*, unsigned long,
            unsigned char*, unsigned long,
            unsigned char*, unsigned long,
            void*);
typedef ret_type t_end(void*);

typedef struct
{   char                *name;
    t_init_and_key      *init_and_key;
    t_init_message      *init_message;
    t_auth_header       *auth_header;
    t_auth_data         *auth_data;
    t_crypt_data        *crypt_data;
    t_compute_tag       *compute_tag;
    t_encrypt           *encrypt;
    t_decrypt           *decrypt;
    t_encrypt_message   *encrypt_message;
    t_decrypt_message   *decrypt_message;
    t_end               *end;
} mode_fns;

#undef mode

#include "ccm.h"
/* special init_message() call for CCM to replace   */
/* t_init_message below when CCM is being used      */
typedef ret_type s_init_message(const unsigned char*,
            unsigned long, length_t, length_t, unsigned long, void*);


#define mode(f) ccm_##f
void mode(functions)(mode_fns f[1])
{
    f->name = "CCM";
    f->init_and_key = mode(init_and_key);
    f->init_message = mode(init_message);
    f->auth_header = mode(auth_header);
    f->auth_data = mode(auth_data);
    f->crypt_data = mode(crypt_data);
    f->compute_tag = mode(compute_tag);
    f->encrypt  = mode(encrypt);
    f->decrypt  = mode(decrypt);
    f->encrypt_message  = mode(encrypt_message);
    f->decrypt_message  = mode(decrypt_message);
    f->end  = mode(end);
}
#undef mode

#include "cwc.h"
#define mode(f) cwc_##f
void mode(functions)(mode_fns f[1])
{
    f->name = "CWC";
    f->init_and_key = mode(init_and_key);
    f->init_message = mode(init_message);
    f->auth_header = mode(auth_header);
    f->auth_data = mode(auth_data);
    f->crypt_data = mode(crypt_data);
    f->compute_tag = mode(compute_tag);
    f->encrypt  = mode(encrypt);
    f->decrypt  = mode(decrypt);
    f->encrypt_message  = mode(encrypt_message);
    f->decrypt_message  = mode(decrypt_message);
    f->end  = mode(end);
}
#undef mode

#include "eax.h"
#define mode(f) eax_##f
void mode(functions)(mode_fns f[1])
{
    f->name = "EAX";
    f->init_and_key = mode(init_and_key);
    f->init_message = mode(init_message);
    f->auth_header = mode(auth_header);
    f->auth_data = mode(auth_data);
    f->crypt_data = mode(crypt_data);
    f->compute_tag = mode(compute_tag);
    f->encrypt  = mode(encrypt);
    f->decrypt  = mode(decrypt);
    f->encrypt_message  = mode(encrypt_message);
    f->decrypt_message  = mode(decrypt_message);
    f->end  = mode(end);
}
#undef mode

#include "gcm.h"
#define mode(f) gcm_##f
void mode(functions)(mode_fns f[1])
{
    f->name = "GCM";
    f->init_and_key = mode(init_and_key);
    f->init_message = mode(init_message);
    f->auth_header = mode(auth_header);
    f->auth_data = mode(auth_data);
    f->crypt_data = mode(crypt_data);
    f->compute_tag = mode(compute_tag);
    f->encrypt  = mode(encrypt);
    f->decrypt  = mode(decrypt);
    f->encrypt_message  = mode(encrypt_message);
    f->decrypt_message  = mode(decrypt_message);
    f->end  = mode(end);
}
#undef mode

#define BLOCK_SIZE AES_BLOCK_SIZE

/*  Find if a line starts with a recognised line designator and
    return its descriptor if it does or ERR if not.
*/
enum des_type find_des(char *s, char **cptr)
{   size_t i = strlen(s);

    while( i && (s[i - 1] < ' ' || s[i - 1] > '\x7e') )
        --i;
    s[i] = '\0';
    if( i == 0 )
        return NUL;
    for(i = 0; i < sizeof(des_name) / sizeof(des_name[0]); ++i)
        if(!strncmp(des_name[i], s, strlen(des_name[i])))
        {   
            *cptr = s + strlen(des_name[i]);
            return des_m[i];
        }
    return ERR;
}

int to_hex(char ch)
{
    return (isdigit(ch) ? 0 : 9) + (ch & 0x0f);
}

unsigned char hex_in(char *s)
{
    return 16 * to_hex(s[0]) + to_hex(s[1]);
}

unsigned int dec_in(char *s)
{   unsigned int n = 0;

    while( isdigit( *s ) )
        n = 10 * n + *s++ - '0';
    return n;
}

void do_test(mode_fns f[1], void* contx, int gen_flag)
{   char            tvi_name[64], tvo_name[64], line[80], *lp;
    FILE            *inf = 0, *outf = 0;
    unsigned char   key[32], iv[256], hdr[256], ptx[256], ctx[256],
                    tag[16], buf[256], tbuf[16], *p;
    int             key_len, iv_len, hdr_len, ptx_len, ctx_len, tag_len,
                    hdr_rpt, ptx_rpt, rpt_cnt, vec_no, *cnt, *rpt = &rpt_cnt, err, i;

    strcpy(tvi_name, in_dir);
    strcat(tvi_name, f->name);
    strcat(tvi_name, ".0");
    if( gen_flag )
    {
        strcpy(tvo_name, out_dir);
        strcat(tvo_name, f->name);
        strcat(tvo_name, ".0");
    }

    for( ; ; )
    {
        tvi_name[strlen(tvi_name) - 1]++;
        if( gen_flag )
        {
            tvo_name[strlen(tvo_name) - 1]++;
            lp = tvo_name - 1;
            while(*++lp)
                *lp = tolower(*lp);
        }
        if(!(inf = fopen(tvi_name, "r")))
            break;

        printf("\nUsing %s test vectors in \"%s\": ", f->name, tvi_name);
        do
        {
            fgets(line, 80, inf);
            if( cstr_cmp(line, "MDE ", 4) == 0 )
                break;
            if( cstr_cmp(line, "END ", 4) == 0 )
                break;
        }
        while
            ( !feof( inf) );

        if(feof(inf) || cstr_cmp(line, "END ", 4) == 0 )
            break;

        if(cstr_cmp(line + 4, f->name, 3) != 0)
        {
            printf("this file does not match %s", f->name);
            break;
        }

        if( gen_flag )
        {
            if(!(outf = fopen(tvo_name, "w")))
                break;
            fprintf(outf, "\nMDE %s", f->name);
        }

        for(err = 0; ; )
        {
            enum des_type   line_is;

            fgets(line, 80, inf);
            if(feof(inf))
                break;

            if(strlen(line) < 4)
            {
                key_len = iv_len = hdr_len = ptx_len =
                    ctx_len = tag_len = rpt_cnt = 0;
                hdr_rpt = ptx_rpt = 1;
                if( gen_flag )
                    fprintf(outf, "\n");
                continue;
            }

            switch( line_is = find_des(line, &lp) )
            {
            case VEC:   vec_no = dec_in(lp);
                        if( gen_flag )
                            fprintf(outf, "\nVEC %04i", vec_no);
                        continue;
            case RPT:   *rpt = dec_in(lp);
                        if( gen_flag )
                            fprintf(outf, "\nRPT %04i", *rpt);
                        continue;
            case NUL:
            case REM:   continue;

            case KEY:   p = key, cnt = &key_len, rpt = &rpt_cnt; break;
            case NCE:   p = iv,  cnt =  &iv_len, rpt = &rpt_cnt; break;
            case HDR:   p = hdr, cnt = &hdr_len, rpt = &hdr_rpt; break;
            case PTX:   p = ptx, cnt = &ptx_len, rpt = &ptx_rpt; break;
            case CTX:   p = ctx, cnt = &ctx_len, rpt = &rpt_cnt; break;
            case TAG:   p = tag, cnt = &tag_len, rpt = &rpt_cnt; break;

            case END:   break;
            case ERR:   printf("\nThe file \'%s\' contains an unrecognised line\n", tvi_name); 
                        break;
            }

            if(line_is == END)
                break;

            if( gen_flag )
            {
                if(line[strlen(line) - 1] == '\n' || line[strlen(line) - 1] == '\r')
                    line[strlen(line) - 1] = '\0';
                if(line_is != CTX && line_is != TAG)
                    fprintf(outf, "\n%s", line);
            }

            if(line_is == REM)
                continue;

            while(*lp != '\n' && *lp != '\0' && *(lp + 1) != '\n' && *(lp + 1) != '\0')
            {
                p[(*cnt)++] = hex_in(lp); lp += 2;
            }

            if(line_is != TAG)
                continue;

            f->init_and_key(key, key_len, contx);

            if(strcmp(f->name, "CCM") == 0)
            {
                int err = ((s_init_message*)f->init_message)(iv, iv_len,
                    hdr_len * hdr_rpt, ptx_len * ptx_rpt, tag_len, contx);
                if(err)
                {
                    if(err == CCM_AUTH_LENGTH_ERROR && hdr_len * hdr_rpt >= 65536 - 256)
                        continue;
                }
            }
            else
                f->init_message(iv, iv_len, contx);

            i = hdr_rpt;
            while(i--)
                f->auth_header(hdr, hdr_len, contx);
#if 1
            i = ptx_rpt;
            while(i--)
            {
                memcpy(buf, ptx, ptx_len);
                f->encrypt(buf, ptx_len, contx);
            }
            if(ptx_rpt == 1 && memcmp(ctx, buf, ctx_len))
                printf("\n\tencrypt ciphertext error on test number %i", vec_no), err++;
#else
            for (i=0; i < ptx_len; i += 16)
            {
                int len = min(16, ptx_len - i);
                memcpy(buf, ptx + i, len);
                f->encrypt(buf, len, contx);
                if(ptx_rpt == 1 && memcmp(ctx + i, buf, len))
                    printf("\n\tencrypt ciphertext error on test number %i", vec_no), err++;
            }
#endif
            f->compute_tag(tbuf, tag_len, contx);
            f->end(contx);

            if( gen_flag )
            {
                for(i = 0; i < ptx_len; ++i)
                {
                    if(i % 32 == 0) fprintf(outf, "\nCTX ");
                    fprintf(outf, "%02x", buf[i]);
                }

                for(i = 0; i < tag_len; ++i)
                {
                    if(i % 32 == 0) fprintf(outf, "\nTAG ");
                    fprintf(outf, "%02x", tbuf[i]);
                }
            }
            else if(memcmp(tag, tbuf, tag_len))
                printf("\n\tencrypt tag error on test number %i", vec_no), err++;

            f->init_and_key(key, key_len, contx);

            if(strcmp(f->name, "CCM") == 0)
                ((s_init_message*)f->init_message)(iv, iv_len,
                    hdr_len * hdr_rpt, ptx_len * ptx_rpt, tag_len, contx);
            else
                f->init_message(iv, iv_len, contx);

            i = hdr_rpt;
            while(i--)
                f->auth_header(hdr, hdr_len, contx);

⌨️ 快捷键说明

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