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

📄 aeslib.c

📁 aesutil是一个小型的库和命令行程序
💻 C
字号:
/* ------------------------------------------------------------------------- Copyright (c) 2002, Markus Lagler <markus.lagler@trivadis.com> Copyright (c) 2002, Tim Tassonis  <timtas@dplanet.ch> 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. DISCLAIMER This software is provided 'as is' with no explcit or implied warranties in respect of any properties, including, but not limited to, correctness and fitness for purpose. -------------------------------------------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <memory.h>#include "aes.h"#include "aeslib.h"#ifdef HAVE_DEV_URANDOMvoid fillrand(char *buf, const int len){	FILE * frand;	frand = fopen("/dev/urandom","r");	fread(buf,1,len,frand);	fclose(frand);	return;}#endif#ifdef WINDOWS/*  A Pseudo Random Number Generator (PRNG) used for the  Initialisation Vector. The PRNG is George Marsaglia's  Multiply-With-Carry (MWC) PRNG that concatenates two  16-bit MWC generators:      x(n)=36969 * x(n-1) + carry mod 2^16      y(n)=18000 * y(n-1) + carry mod 2^16  to produce a combined PRNG with a period of about 2^60.  The Pentium cycle counter is used to initialise it. This  is crude but the IV does not really need to be secret.*/void cycles(unsigned long *rtn){	__asm               /*  read the Pentium Time Stamp Counter */	{		_emit   0x0f        /* complete pending operations */		_emit   0xa2		_emit   0x0f        /* read time stamp counter */		_emit   0x31		mov     ebx,rtn		mov     [ebx],eax		mov     [ebx+4],edx		_emit   0x0f        /* complete pending operations */		_emit   0xa2	}}#define RAND(a,b) (((a = 36969 * (a & 65535) + (a >> 16)) << 16) + \                    (b = 18000 * (b & 65535) + (b >> 16))  )void fillrand(char *buf, const int len){	static unsigned long a[2], mt = 1, count = 4;	static char          r[4];	int                  i;	if(mt) { mt = 0; cycles(a); }	for(i = 0; i < len; ++i) {	        if(count == 4) {			*(unsigned long*)r = RAND(a[0], a[1]);			count = 0;		}		buf[i] = r[count++];	}}#endifint encbuf(char* in, int in_len, char* out, aes_ctx *ctx, int* out_len){   	char            buf[BLOCK_LEN], dbuf[2 * BLOCK_LEN];    unsigned long   i, l, rlen;	char *pos_out, *pos_in;    fillrand(dbuf, BLOCK_LEN);              // set a random IV	rlen = in_len;	pos_out = out;	pos_in = in;    if(rlen < BLOCK_LEN)                    // file length of less than one block    {		memcpy(dbuf + BLOCK_LEN, in, rlen);		l = rlen;        for(i = 0; i < l; ++i)              // xor file bytes with IV bytes            dbuf[i + BLOCK_LEN] ^= dbuf[i];        aes_enc_blk(dbuf, dbuf, ctx);   // encrypt lower half of buffer        // encrypt bytes from position l to position l + BLOCK_LEN - the        // file bytes plus a second encryption of some of the IV bytes        aes_enc_blk(dbuf + l, dbuf + l, ctx);        l += BLOCK_LEN;                     // write the encrypted bytes		memcpy(out, dbuf, l);		*out_len = l;    }    else    {        aes_enc_blk(dbuf, buf, ctx);    // encrypt and write IV block		memcpy(pos_out, buf, BLOCK_LEN);		pos_out += BLOCK_LEN;		*out_len = BLOCK_LEN;		while(rlen)        {                                   // read a block and reduce remaining			memcpy(buf, pos_in, BLOCK_LEN);			pos_in += BLOCK_LEN;			l = BLOCK_LEN;			rlen -= l;            for(i = 0; i < BLOCK_LEN; ++i)  // do CBC chaining prior to                buf[i] ^= dbuf[i];          // encryption            aes_enc_blk(buf, dbuf, ctx);            if(rlen < BLOCK_LEN)            // if only a part block remains            {				memcpy(dbuf+BLOCK_LEN, pos_in, rlen);                // encrypt from position rlen to rlen + BLOCK_LEN - the last                // file bytes plus a part of the last encrypted block - this                // is called 'ciphertext stealing'                for(i = 0; i < rlen; ++i)   // do CBC chaining prior to                    dbuf[i + BLOCK_LEN] ^= dbuf[i];     // encryption                aes_enc_blk(dbuf + rlen, dbuf + rlen, ctx);                l = rlen + BLOCK_LEN;       // set final buffer length				rlen = 0;            }			memcpy(pos_out, dbuf, l);			pos_out += l;			*out_len += l;        }    }    return 0;}int decbuf(char* in, int in_len, char* out, aes_ctx *ctx, int *out_len){   	char            buf1[BLOCK_LEN], buf2[BLOCK_LEN], dbuf[2 * BLOCK_LEN];    char            *b1, *b2, *bt;    unsigned long   i, l, rlen;	char            *pos_in, *pos_out;	rlen = in_len;	pos_in = in;	pos_out = out;    if(rlen < 2 * BLOCK_LEN)                // original length of less than one block    {		memcpy(dbuf, in, rlen);		l = rlen;		        l -= BLOCK_LEN;                     // original file length        // decrypt from position l to position l + BLOCK_LEN        aes_dec_blk(dbuf + l, dbuf + l, ctx);        aes_dec_blk(dbuf, dbuf, ctx);   // decrypt lower half of buffer        for(i = 0; i < l; ++i)              // remove IV xor            dbuf[i] ^= dbuf[i + BLOCK_LEN];		memcpy(out, dbuf, l);		*out_len = l;    }    else    {   // we need two input buffers because we have to keep the previous        // ciphertext block - the pointers b1 and b2 are swapped once per        // loop so that b2 points to new ciphertext block and b1 to the        // last ciphertext block        rlen -= BLOCK_LEN; b1 = buf1; b2 = buf2;		memcpy(b1, pos_in, BLOCK_LEN);		pos_in += BLOCK_LEN;		*out_len = 0;        aes_dec_blk(b1, b1, ctx);       // and decrypt it		while (rlen)        {                                   // read a block and reduce remaining			if (rlen < BLOCK_LEN)			{				memcpy(b2, pos_in, rlen);				l = rlen;			}			else			{				memcpy(b2, pos_in, BLOCK_LEN);				pos_in += BLOCK_LEN;			    l = BLOCK_LEN;			}			rlen -= l;            if(rlen < BLOCK_LEN)            // if only a part block remains            {                for(i = 0; i < BLOCK_LEN; ++i)  // move bytes from last but                    dbuf[i] = b2[i];        // one block into lower half of dbuf				if (rlen)				{					memcpy(dbuf + BLOCK_LEN, pos_in, rlen);				}				                // decrypt from position rlen to rlen + BLOCK_LEN - that is                // the file bytes plus a part of the last but one encrypted                // block                aes_dec_blk(dbuf + rlen, dbuf + rlen, ctx);                for(i = 0; i < rlen; ++i)   // unchain the CBC using the                    dbuf[i + BLOCK_LEN] ^= dbuf[i];   // last ciphertext block                // set output buffer and correct final length                b2 = dbuf; l = rlen + BLOCK_LEN;				rlen = 0;		    }            aes_dec_blk(b2, dbuf, ctx); // decrypt the input buffer            for(i = 0; i < BLOCK_LEN; ++i)  // unchain the CBC using the                dbuf[i] ^= b1[i];           // last ciphertext block			memcpy(pos_out, dbuf, l);			pos_out += l;			*out_len += l;            bt = b1, b1 = b2, b2 = bt;      // swap the input buffer pointers        }    }    return 0;}char* aes_enc(char *in, int in_len, char *key, int key_len, int* out_len){	aes_ctx ctx[1];	char *out;	char local_key[FIX_KEY_LEN]; // always use key of 32 byte length	aes_fret ret;		out = (char*) malloc(in_len + 2*BLOCK_LEN); // 1 BLOCK IV and BLOCK at the end	memset(ctx, 0x0, sizeof(ctx));		// key run up	if (key_len < FIX_KEY_LEN)	{		memset(local_key, 0x12, FIX_KEY_LEN);   // if the entred key is shorter as the desired key length		memcpy(local_key, key, key_len);		// add simple padding (fill up with 0x12)	}	else	{		memcpy(local_key, key, FIX_KEY_LEN);	}	ret = aes_enc_key(local_key, FIX_KEY_LEN, ctx);	if (ret != aes_good)		return NULL;	encbuf(in, in_len, out, ctx, out_len);	return out;}char* aes_dec(char *in, int in_len, char *key, int key_len, int* out_len){	aes_ctx ctx[1];	char *out;	char local_key[FIX_KEY_LEN]; // always use key of 32 byte length	aes_fret ret;		out = (char*) malloc(in_len);	memset(ctx, 0x0, sizeof(ctx));		// key run up	if (key_len < FIX_KEY_LEN)	{		memset(local_key, 0x12, FIX_KEY_LEN);   // if the entred key is shorter as the desired key length		memcpy(local_key, key, key_len);		// add simple padding (fill up with 0x12)	}	else	{		memcpy(local_key, key, FIX_KEY_LEN);	}	ret = aes_dec_key(local_key, FIX_KEY_LEN, ctx);	if (ret != aes_good)		return NULL;	decbuf(in, in_len, out, ctx, out_len);	return out;}

⌨️ 快捷键说明

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