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

📄 pgpaes.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Optimised ANSI C code for the AES cipher AKA Rijndael
 * authors: v1.0: Antoon Bosselaers
 *          v2.0: Vincent Rijmen
 * Formatted for PGP.
 * $Id: pgpAES.c,v 1.9 2001/10/05 23:55:00 hal Exp $

 */

#include "pgpSDKBuildFlags.h"

#ifndef PGP_AES
#error you must define PGP_AES one way or the other
#endif

#if PGP_AES	/* [ */

#include "pgpConfig.h"

#include "pgpSymmetricCipherPriv.h"
#include "pgpAES.h"
#include "pgpMem.h"
#include "pgpUsuals.h"

#include <stdio.h>
#include <stdlib.h>

#define MAXKC				(256/32)
#define MAXROUNDS			14

typedef unsigned char		word8;	
typedef unsigned short		word16;	
typedef unsigned int		word32;

static int rijndaelKeySched (word8 k[MAXKC][4], int keyBits,  
		word8 rk[MAXROUNDS+1][4][4], int rounds);
static int rijndaelEncrypt (word8 a[16], word8 b[16], 
		word8 rk[MAXROUNDS+1][4][4], int rounds);
static int rijndaelKeyEnctoDec (int keyBits, word8 W[MAXROUNDS+1][4][4],
		int rounds);
static int rijndaelKeyDectoEnc (int keyBits, word8 W[MAXROUNDS+1][4][4],
		int rounds);
static int rijndaelDecrypt (word8 a[16], word8 b[16],
		word8 rk[MAXROUNDS+1][4][4], int rounds);


#if PGP_UNIX_SOLARIS
/* Hosts which can't dereference arbitrary pointers as word32s */
#define AES_WORD_ALIGNMENT 1
#else
#define AES_WORD_ALIGNMENT 0
#endif

#define SC	((BC - 4) >> 1)

#include "pgpAESboxes.h"
#if ! PGP_OSX	/*	These do not appear to be used.	*/
static word8 shifts[3][4][2] = {
   { { 0, 0 },
     { 1, 3 },
     { 2, 2 },
     { 3, 1 } },
   
   { { 0, 0 },
     { 1, 5 },
     { 2, 4 },
     { 3, 3 } },
   
   { { 0, 0 },
     { 1, 7 },
     { 3, 5 },
     { 4, 4 } }
}; 
#endif

static word8 mul(word8 a, word8 b) {
   /* multiply two elements of GF(2^m)
    * needed for MixColumn and InvMixColumn
    */
	if (a && b)
		return Alogtable[(Logtable[a] + Logtable[b])%255];
	else
		return 0;
}

#if ! PGP_OSX	/*	These do not appear to be used	*/
static void KeyAddition(word8 a[4][4], word8 rk[4][4], word8 BC) {
	/* Exor corresponding text input and round key input bytes
	 */
	int i, j;
	
	for(i = 0; i < BC; i++)
   	for(j = 0; j < 4; j++)
			a[i][j] ^= rk[i][j];
}

static void ShiftRow(word8 a[4][4], word8 d, word8 BC) {
	/* Row 0 remains unchanged
	 * The other three rows are shifted a variable amount
	 */
	word8 tmp[4];
	int i, j;
	
	for(i = 1; i < 4; i++) {
		for(j = 0; j < BC; j++)
			tmp[j] = a[(j + shifts[SC][i][d]) % BC][i];
		for(j = 0; j < BC; j++)
			a[j][i] = tmp[j];
	}
}

static void Substitution(word8 a[4][4], word8 box[256], word8 BC) {
	/* Replace every byte of the input by the byte at that place
	 * in the nonlinear S-box
	 */
	int i, j;
	
	for(i = 0; i < BC; i++)
		for(j = 0; j < 4; j++)
			a[i][j] = box[a[i][j]] ;
}
#endif
   
static void MixColumn(word8 a[4][4], word8 BC) {
        /* Mix the four bytes of every column in a linear way
	 */
	word8 b[4][4];
	int i, j;
		
	for(j = 0; j < BC; j++)
		for(i = 0; i < 4; i++)
			b[j][i] = mul(2,a[j][i])
				^ mul(3,a[j][(i + 1) % 4])
				^ a[j][(i + 2) % 4]
				^ a[j][(i + 3) % 4];
	for(i = 0; i < 4; i++)
		for(j = 0; j < BC; j++)
			a[j][i] = b[j][i];
}

static void InvMixColumn(word8 a[4][4], word8 BC) {
        /* Mix the four bytes of every column in a linear way
	 * This is the opposite operation of Mixcolumn
	 */
	int j;

	for(j = 0; j < BC; j++)
		*((word32*)a[j]) = *((word32*)U1[a[j][0]])
								^ *((word32*)U2[a[j][1]])
								^ *((word32*)U3[a[j][2]])
								^ *((word32*)U4[a[j][3]]);


}

int rijndaelKeySched (word8 k[MAXKC][4], int keyBits,
					  word8 W[MAXROUNDS+1][4][4], int rounds)
{
	/* Calculate the necessary round keys
	 * The number of calculations depends on keyBits and blockBits
	 */ 
	int j, r, t, rconpointer = 0;
	word8 tk[MAXKC][4];
	int KC = rounds - 6;
	
	(void) keyBits;		/* Silence compiler warnings */

/*
 * Copy to tk array without requiring k to have word32 safe alignment
	for(j = KC-1; j >= 0; j--)
		*((word32*)tk[j]) = *((word32*)k[j]);
 */
	pgpCopyMemory( k, tk, KC*4 );
	r = 0;
	t = 0;
	/* copy values into round key array */
	for(j = 0; (j < KC) && (r < (rounds+1)); ) {
		for (; (j < KC) && (t < 4); j++, t++)
			*((word32*)W[r][t]) = *((word32*)tk[j]);
		if (t == 4) {
			r++;
			t = 0;
		}
	}
		
	while (r < (rounds+1)) { /* while not enough round key material calculated */
		/* calculate new values */
		tk[0][0] ^= S[tk[KC-1][1]];
		tk[0][1] ^= S[tk[KC-1][2]];
		tk[0][2] ^= S[tk[KC-1][3]];
		tk[0][3] ^= S[tk[KC-1][0]];
		tk[0][0] ^= rcon[rconpointer++];

		if (KC != 8)
			for(j = 1; j < KC; j++)
				*((word32*)tk[j]) ^= *((word32*)tk[j-1]);
		else {
			for(j = 1; j < KC/2; j++)
				*((word32*)tk[j]) ^= *((word32*)tk[j-1]);
			tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
			tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
			tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
			tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
			for(j = KC/2 + 1; j < KC; j++)
				*((word32*)tk[j]) ^= *((word32*)tk[j-1]);
		}
		/* copy values into round key array */
		for(j = 0; (j < KC) && (r < (rounds+1)); ) {
			for (; (j < KC) && (t < 4); j++, t++)
				*((word32*)W[r][t]) = *((word32*)tk[j]);
			if (t == 4) {
				r++;
				t = 0;
			}
		}
	}		

	return 0;
}

static int rijndaelKeyEnctoDec (int keyBits, word8 W[MAXROUNDS+1][4][4],
								int rounds)
{
	int r;

	(void) keyBits;		/* Silence compiler warnings */

	for (r = 1; r < rounds; r++) {
		InvMixColumn(W[r], 4);
	}
	return 0;
}	

static int rijndaelKeyDectoEnc (int keyBits, word8 W[MAXROUNDS+1][4][4],
								int rounds)
{
	int r;

	(void) keyBits;		/* Silence compiler warnings */

	for (r = 1; r < rounds; r++) {
		MixColumn(W[r], 4);
	}
	return 0;
}	

/* rk is word32 aligned, but in and out may not be */
static int rijndaelEncrypt (word8 in[16], word8 out[16],
							word8 rk[MAXROUNDS+1][4][4], int rounds)
{
	/* Encryption of one block. 
	 */
	int r;
#if AES_WORD_ALIGNMENT
	word32 dummy;
    word8 a[16], b[16];
#else
    word8 *a, *b;
#endif
    word8 temp[4][4];

#if AES_WORD_ALIGNMENT
    pgpCopyMemory( in, a, sizeof(a) );
#else
	a = in;
	b = out;
#endif

    *((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[0][0]);
    *((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[0][1]);
    *((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[0][2]);
    *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[0][3]);
    *((word32*)b) = *((word32*)T1[temp[0][0]])
           ^ *((word32*)T2[temp[1][1]])
           ^ *((word32*)T3[temp[2][2]]) 
           ^ *((word32*)T4[temp[3][3]]);
    *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
           ^ *((word32*)T2[temp[2][1]])
           ^ *((word32*)T3[temp[3][2]]) 
           ^ *((word32*)T4[temp[0][3]]);
    *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
           ^ *((word32*)T2[temp[3][1]])
           ^ *((word32*)T3[temp[0][2]]) 
           ^ *((word32*)T4[temp[1][3]]);
    *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
           ^ *((word32*)T2[temp[0][1]])
           ^ *((word32*)T3[temp[1][2]]) 
           ^ *((word32*)T4[temp[2][3]]);
   for(r = 1; r < rounds-1; r++) {
		*((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
		*((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
		*((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
		*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
   *((word32*)b) = *((word32*)T1[temp[0][0]])
           ^ *((word32*)T2[temp[1][1]])
           ^ *((word32*)T3[temp[2][2]]) 
           ^ *((word32*)T4[temp[3][3]]);
   *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
           ^ *((word32*)T2[temp[2][1]])
           ^ *((word32*)T3[temp[3][2]]) 
           ^ *((word32*)T4[temp[0][3]]);
   *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
           ^ *((word32*)T2[temp[3][1]])
           ^ *((word32*)T3[temp[0][2]]) 
           ^ *((word32*)T4[temp[1][3]]);
   *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
           ^ *((word32*)T2[temp[0][1]])
           ^ *((word32*)T3[temp[1][2]]) 
           ^ *((word32*)T4[temp[2][3]]);
   }
   /* last round is special */   
	*((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[rounds-1][0]);
	*((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[rounds-1][1]);
	*((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[rounds-1][2]);
	*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[rounds-1][3]);
   b[0] = T1[temp[0][0]][1];
   b[1] = T1[temp[1][1]][1];
   b[2] = T1[temp[2][2]][1]; 
   b[3] = T1[temp[3][3]][1];
   b[4] = T1[temp[1][0]][1];
   b[5] = T1[temp[2][1]][1];
   b[6] = T1[temp[3][2]][1]; 
   b[7] = T1[temp[0][3]][1];
   b[8] = T1[temp[2][0]][1];
   b[9] = T1[temp[3][1]][1];
   b[10] = T1[temp[0][2]][1]; 
   b[11] = T1[temp[1][3]][1];
   b[12] = T1[temp[3][0]][1];
   b[13] = T1[temp[0][1]][1];
   b[14] = T1[temp[1][2]][1]; 
   b[15] = T1[temp[2][3]][1];
	*((word32*)b) ^= *((word32*)rk[rounds][0]);
	*((word32*)(b+4)) ^= *((word32*)rk[rounds][1]);
	*((word32*)(b+8)) ^= *((word32*)rk[rounds][2]);
	*((word32*)(b+12)) ^= *((word32*)rk[rounds][3]);

#if AES_WORD_ALIGNMENT
    pgpCopyMemory( b, out, sizeof(b) );
#endif

	return 0;
}


/* rk is word32 aligned, but in and out may not be */
static int rijndaelDecrypt (word8 in[16], word8 out[16],
							word8 rk[MAXROUNDS+1][4][4], int rounds)

⌨️ 快捷键说明

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