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

📄 rijndael_api.c

📁 minux操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	rijndael-api.c - Rijndael encryption programming interface. *							Author: Kees J. Bot *								3 Nov 2000 * Heavily based on the original API code by Antoon Bosselaers, * Vincent Rijmen, and Paulo Barreto, but with a different interface. * * Read this code top to bottom, not all comments are repeated. */#include <stdlib.h>#include <string.h>#include <sys/types.h>#include "rijndael-alg.h"#include "rijndael-api.h"/* Map a byte (?) address to a word address or vv. */#define W(a)	((word32 *) (a))#define B(a)	((word8 *) (a))#if STRICT_ALIGN/* This machine checks alignment religiously.  (The code is not proper with * respect to alignment.  We need a compiler that doesn't muck about with byte * arrays that follow words in structs, and that places automatic variables * at word boundaries if not odd-sized.  Most compilers are this nice.) */#define aligned(a)		(((unsigned) (a) & 3) == 0)#define aligned2(a1, a2)	aligned((unsigned) (a1) | (unsigned) (a2))static void blockcpy(void *dst, const void *src){    int i= 0;    do {	B(dst)[i+0] = B(src)[i+0];	B(dst)[i+1] = B(src)[i+1];	B(dst)[i+2] = B(src)[i+2];	B(dst)[i+3] = B(src)[i+3];    } while ((i += 4) < 16);}#else /* !STRICT_ALIGN *//* This machine doesn't mind misaligned accesses much. */#define aligned(a)		((void) (a), 1)#define aligned2(a1, a2)	((void) (a1), (void) (a2), 1)#if __GNUC____inline#endifstatic void blockcpy(void *dst, const void *src){    W(dst)[0] = W(src)[0];    W(dst)[1] = W(src)[1];    W(dst)[2] = W(src)[2];    W(dst)[3] = W(src)[3];}#endif /* !STRICT_ALIGN */#define between(a, c, z)	((unsigned) (c) - (a) <= (unsigned) (z) - (a))int rijndael_makekey(rd_keyinstance *key,	size_t keylen, const void *keymaterial){    word8 k[MAXKC][4];    /* Initialize key schedule: */    if (keylen == RD_KEY_HEX) {	const word8 *kp;	int c, b;	kp= keymaterial;	keylen= 0;	for (;;) {	    c= *kp++;	    if (between('0', c, '9')) b= (c - '0' + 0x0) << 4;	    else	    if (between('a', c, 'f')) b= (c - 'a' + 0xa) << 4;	    else	    if (between('A', c, 'F')) b= (c - 'A' + 0xA) << 4;	    else break;	    c= *kp++;	    if (between('0', c, '9')) b |= (c - '0' + 0x0);	    else	    if (between('a', c, 'f')) b |= (c - 'a' + 0xa);	    else	    if (between('A', c, 'F')) b |= (c - 'A' + 0xA);	    else break;	    if (keylen >= 256/8) return RD_BAD_KEY_MAT;	    B(k)[keylen++] = b;	}	if (c != 0) return RD_BAD_KEY_MAT;	if (keylen != 128/8 && keylen != 192/8 && keylen != 256/8) {	    return RD_BAD_KEY_MAT;	}    } else {	if (keylen != 128/8 && keylen != 192/8 && keylen != 256/8) {	    return RD_BAD_KEY_MAT;	}	memcpy(k, keymaterial, keylen);    }    key->rounds= keylen * 8 / 32 + 6;    rijndael_KeySched(k, key->encsched, key->rounds);    memcpy(key->decsched, key->encsched, sizeof(key->decsched));    rijndael_KeyEncToDec(key->decsched, key->rounds);    return 0;}ssize_t rijndael_ecb_encrypt(rd_keyinstance *key,	const void *input, void *output, size_t length, void *dummyIV){    /* Encrypt blocks of data in Electronic Codebook mode. */    const word8 *inp= input;    word8 *outp= output;    size_t i, nr_blocks, extra;    word32 in[4], out[4];    word8 t;    /* Compute the number of whole blocks, and the extra bytes beyond the     * last block.  Those extra bytes, if any, are encrypted by stealing     * enough bytes from the previous encrypted block to make a whole block.     * This is done by encrypting the last block, exchanging the first few     * encrypted bytes with the extra bytes, and encrypting the last whole     * block again.     */    nr_blocks= length / 16;    if ((extra= (length % 16)) > 0) {	if (nr_blocks == 0) return RD_BAD_BLOCK_LENGTH;	nr_blocks--;    }    /* Encrypt a number of blocks. */    if (aligned2(inp, outp)) {	for (i= 0; i < nr_blocks; i++) {	    rijndael_Encrypt(inp, outp, key->encsched, key->rounds);	    inp += 16;	    outp += 16;	}    } else {	for (i= 0; i < nr_blocks; i++) {	    blockcpy(in, inp);	    rijndael_Encrypt(in, out, key->encsched, key->rounds);	    blockcpy(outp, out);	    inp += 16;	    outp += 16;	}    }    /* Encrypt extra bytes by stealing from the last full block. */    if (extra > 0) {	blockcpy(in, inp);	rijndael_Encrypt(in, out, key->encsched, key->rounds);	for (i= 0; i < extra; i++) {	    t= B(out)[i];	    B(out)[i] = inp[16 + i];	    outp[16 + i] = t;	}	rijndael_Encrypt(out, out, key->encsched, key->rounds);	blockcpy(outp, out);    }    return length;}ssize_t rijndael_ecb_decrypt(rd_keyinstance *key,	const void *input, void *output, size_t length, void *dummyIV){    /* Decrypt blocks of data in Electronic Codebook mode. */    const word8 *inp= input;    word8 *outp= output;    size_t i, nr_blocks, extra;    word32 in[4], out[4];    word8 t;    nr_blocks= length / 16;    if ((extra= (length % 16)) > 0) {	if (nr_blocks == 0) return RD_BAD_BLOCK_LENGTH;	nr_blocks--;    }    /* Decrypt a number of blocks. */    if (aligned2(inp, outp)) {	for (i= 0; i < nr_blocks; i++) {	    rijndael_Decrypt(inp, outp, key->decsched, key->rounds);	    inp += 16;	    outp += 16;	}    } else {	for (i= 0; i < nr_blocks; i++) {	    blockcpy(in, inp);	    rijndael_Decrypt(in, out, key->decsched, key->rounds);	    blockcpy(outp, out);	    inp += 16;	    outp += 16;	}    }    /* Decrypt extra bytes that stole from the last full block. */    if (extra > 0) {	blockcpy(in, inp);	rijndael_Decrypt(in, out, key->decsched, key->rounds);	for (i= 0; i < extra; i++) {	    t= B(out)[i];	    B(out)[i] = inp[16 + i];	    outp[16 + i] = t;	}	rijndael_Decrypt(out, out, key->decsched, key->rounds);	blockcpy(outp, out);    }    return length;}ssize_t rijndael_cbc_encrypt(rd_keyinstance *key,	const void *input, void *output, size_t length, void *IV){    /* Encrypt blocks of data in Cypher Block Chaining mode. */    const word8 *inp= input;    word8 *outp= output;    size_t i, nr_blocks, extra;    word32 in[4], out[4], iv[4], *ivp;    word8 t;    nr_blocks= length / 16;    if ((extra= (length % 16)) > 0) {	if (nr_blocks == 0) return RD_BAD_BLOCK_LENGTH;	nr_blocks--;    }    /* Each input block is first XORed with the previous encryption result.     * The "Initialization Vector" is used to XOR the first block with.     * When done the last crypted block is stored back as the new IV to be     * used for another call to this function.     */    ivp= aligned(IV) ? IV : (blockcpy(iv, IV), iv);    if (aligned2(inp, outp)) {	for (i= 0; i < nr_blocks; i++) {	    in[0] = W(inp)[0] ^ ivp[0];	    in[1] = W(inp)[1] ^ ivp[1];	    in[2] = W(inp)[2] ^ ivp[2];	    in[3] = W(inp)[3] ^ ivp[3];	    rijndael_Encrypt(in, outp, key->encsched, key->rounds);	    ivp= W(outp);	    inp += 16;	    outp += 16;	}    } else {	for (i= 0; i < nr_blocks; i++) {	    blockcpy(in, inp);	    in[0] ^= ivp[0];	    in[1] ^= ivp[1];	    in[2] ^= ivp[2];	    in[3] ^= ivp[3];	    rijndael_Encrypt(in, out, key->encsched, key->rounds);	    blockcpy(outp, out);	    ivp= out;	    inp += 16;	    outp += 16;	}    }    if (extra > 0) {	blockcpy(in, inp);	in[0] ^= ivp[0];	in[1] ^= ivp[1];	in[2] ^= ivp[2];	in[3] ^= ivp[3];	rijndael_Encrypt(in, out, key->encsched, key->rounds);	for (i= 0; i < extra; i++) {	    t= B(out)[i];	    B(out)[i] ^= inp[16 + i];	    outp[16 + i] = t;	}	rijndael_Encrypt(out, out, key->encsched, key->rounds);	blockcpy(outp, out);	ivp= out;    }    blockcpy(IV, ivp);		/* Store last IV back. */    return length;}ssize_t rijndael_cbc_decrypt(rd_keyinstance *key,	const void *input, void *output, size_t length, void *IV){    /* Decrypt blocks of data in Cypher Block Chaining mode. */    const word8 *inp= input;    word8 *outp= output;

⌨️ 快捷键说明

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