Evoluator

Hello to all,

I am new to C#, actually very new! I need some general help to translate this copyright protected code from C to C#.

The following code has to files a .h and a .c file. I just need to know how should I lay the code out!

I also need to know what I should do with the header file!

Thanks for your help.
I have enclsed the .c file in another post since its length exceded the maximum allowed.



Code Block ~ aes.h

/* aes.h */

/* AES Cipher header file for ANSI C Submissions
* Lawrence E. Bassham III
* Computer Security Division
* National Institute of Standards and Technology
*
* April 15, 1998
*
* Modified for IBM submission
* David Safford
* 4/16/1998
*/

#include <stdio.h>

/*************************************************************************
*
* NIST High Level C API, with some IBM additions
*
************************************************************************/

#define TRUE 1
#define FALSE 0

#define DIR_ENCRYPT 0 /* Are we encrypting */
#define DIR_DECRYPT 1 /* Are we decrypting */
#define MODE_ECB 1 /* Are we ciphering in ECB mode */
#define MODE_CBC 2 /* Are we ciphering in CBC mode */
#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode */

#define BAD_KEY_DIR -1 /* Key direction is invalid */
#define BAD_KEY_MAT -2 /* Key material not of correct length */
#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */
#define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */
#define BAD_CIPHER_STATE -5 /* Cipher in wrong state */

typedef unsigned char BYTE;

/* IBM Addition - a WORD must be 32 bits for this implementation */
typedef unsigned long WORD;

/* IBM specific defines: these parameters can be changed */
#define NUM_MIX 8 /* number of mixing rounds per stage */
#define NUM_ROUNDS 16 /* number of full core rounds */
#define NUM_SETUP 7 /* number of key setup mixing rounds */

/* IBM specific defines: these parameters are fixed for this implementation */
#define W 32 /* number of bits in a word */
#define NUM_DATA 4 /* data block size in words */
#define EKEY_WORDS (2*(NUM_DATA+NUM_ROUNDS)) /* number of subkey words */

/* IBM modified values */
#define MAX_KEY_SIZE (EKEY_WORDS*8) /* max ASCII char's needed for a key */
#define MAX_IV_SIZE (NUM_DATA*4) /* max bytes's needed for an IV */

/* The structure for key information */
typedef struct {
BYTE direction; /* Key used for encrypting or decrypting */
int keyLen; /* Length of the key in BITS */
char keyMaterial[MAX_KEY_SIZE+1]; /* Raw key data in ASCII */
WORD E[EKEY_WORDS]; /* IBM addition for mars expanded key */
} keyInstance;

/* The structure for cipher information */
typedef struct {
BYTE mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */
BYTE IV[MAX_IV_SIZE]; /* initial binary IV BYTE for chaining */
WORD CIV[NUM_DATA]; /* IBM addition: current IV in binary WORDs */
} cipherInstance;

/* NIST High level function protoypes */
int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial);

int cipherInit(cipherInstance *cipher, BYTE mode, char *IV);

int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
int inputLen, BYTE *outBuffer);

int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
int inputLen, BYTE *outBuffer);

/*************************************************************************
*
* IBM Low Level (WORD Oriented) API
*
************************************************************************/

/* setup a mars expanded key
*
* k (input) is the number of words in the key
* kp (input) is a pointer to the array of k key words
* ep (output) is a pointer to an array of EKEY_WORDS expanded subkey WORDs
*/
int mars_setup(int k, WORD *kp, WORD *ep);

/* The basic mars encryption of one block (of NUM_DATA WORDS) */
void mars_encrypt(WORD *in, WORD *out, WORD *ep);

/* mars decryption is simply encryption in reverse */
void mars_decrypt(WORD *in, WORD *out, WORD *ep)


Code Block



Re: Visual C# Language Transition from C to C#

Evoluator



Code Block ~ mars.c

//* mars.c optimized C code - copyright(c) 1998 IBM
*
* This code implements both the NIST high level C API (version 5)
* and an underlying IBM defined low level (WORD oriented) C API.
*/

/* Revisions log:
*
* Aug 1999, Shai - the "tweaked" key schedule
* Apr 1998, Dave && Shai - new key scheduling, new sbox, NIST API
* Mar 1998, Shai Halevi - adapted to the latest variant of mars
* Feb 1998, Dave Safford - created
*/

/* Compilation using pcg's version of gcc:
* gcc -Wall -pedantic -c -O6 -fomit-frame-pointer -mcpu=pentiumpro
* -DINTEL_GCC tests.c mars-opt.c
*
* Compilation using xlc on AIX:
* xlc -c -O3 -DAIX_XLC mars-opt.c
*
* Compilation using Borland C++ 5.0 from a DOS command line:
* bcc32 -Oi -6 -v -A -a4 -O2 -DKAT tests.c mars-opt.c
*
* Useful compilation defines:
* NO_MIX - do not execute the mixing phases (core only)
* INTEL_GCC - optimized for pentiumpro and djgpp/gcc compiler
* AIX_XLC - optimized for powerpc/AIX with xlc compiler
* SWAP_BYTES - force endian conversion (eg __BYTE_ORDER not supported)
* IVT - add intermediate values test outputs (this slows
* down encryption and decryption significantly)
*/

#include "aes.h"

/* The low level mars routines are completely WORD oriented, and
* endian neutral. The high level NIST routines provide BYTE oriented
* inputs and outputs, thus raising the endian issue when converting
* between BYTEs and WORDs. For these conversions, mars assumes
* little endian order. On a big endian machine, we define BSWAP()
* to do the conversions. BSWAP() is about the best you can do in C.
* Real implementations will undoubtedly use inline ASM, as most risc
* machines can do this in one instruction.
*
* Make a best guess on platform endianness; This works on linux, AIX,
* and W95. For other platforms, you may have to manually define SWAP_BYTES
* on a big endian machine if this guessing doesn't work.
*/
#ifdef _AIX
#define SWAP_BYTES
#else
#ifdef __linux__
#include <endian.h>
#ifdef __BYTE_ORDER
#if __BYTE_ORDER == __BIG_ENDIAN
#define SWAP_BYTES
#endif
#endif
#endif
#endif
#ifdef SWAP_BYTES
#define BSWAP(x) \
( (( x ) << 24) | \
(((x)&0xff00 ) << 8 ) | \
(((x)&0xff0000) >> 8 ) | \
(( x ) >> 24) )
#else
#define BSWAP(x) (x)
#endif

/* Some compiler optimizers will recognize certain rotation idioms,
* and reduce them to native rotation instructions. These idioms
* have been found to work for GCC on Intel, and XLC on RS6000.
* Nothing seems to work on Borland C++ 5.0, although we can leave
* out the mask on 'b'.
*/
#ifdef INTEL_GCC
#define LROTATE(a,b) (((a)<<(int)(b)) | ((a)>>(W - (int)(b))))
#define RROTATE(a,b) (((a)>>(int)(b)) | ((a)<<(W - (int)(b))))
#else
#ifdef AIX_XLC
#define LROTATE(a,b) ( ((a)>>(W - (b))) | ((a)<<(b)) )
#define RROTATE(a,b) ( ((a)<<(W - (b))) | ((a)>>(b)) )
#else
#ifdef __BORLANDC__
#define LROTATE(a,b) ( ((a)>>(W - (b))) | ((a)<<(b)) )
#define RROTATE(a,b) ( ((a)<<(W - (b))) | ((a)>>(b)) )
#else
#define LROTATE(a,b) (((a)<<(int)(b&31)) | ((a)>>(W - (int)(b&31))))
#define RROTATE(a,b) (((a)>>(int)(b&31)) | ((a)<<(W - (int)(b&31))))
#endif
#endif
#endif

/* two 8 x 32 sboxes - stored together to save a pointer
* these sboxes were generated with buf[3] = 0x02917d59, as
* chosen by sbox.c, which had the following output:
* Afte 54817140, (38023 fail) new min j = 43089241 (0x2917d59)
* test 0 eval 0.044922 (single bit correlation)
* test 1 eval 0.033203 (single bit bias)
* test 2 eval 0.031250 (consecutive bit bias)
* test 3 eval 0.007813 (parity bias)
* test 4 eval 0.148438 (avalanche)
*/
static WORD S[512] = { there are 32bit words here!
};

/*
* The following implements Intermediate Values Tests Macros.
* Since internal words are always kept little-endian, always
* swap bytes before displaying.
*/
#ifdef IVT
int ivt_debug = 0;
FILE *ivt_fp;
int ivt_l = 0;
#define IVTSWAP(x) \
( (( x ) << 24) | \
(((x)&0xff00 ) << 8 ) | \
(((x)&0xff0000) >> 8 ) | \
(( x ) >> 24) )
#define IVT_DEBUG(a,b,c,d) \
if (ivt_debug) \
fprintf(ivt_fp,"IV%d=%8.8lx %8.8lx %8.8lx %8.8lx\n",ivt_l++,\
IVTSWAP(a),IVTSWAP(b),IVTSWAP(c),IVTSWAP(d));
#else
#define IVT_DEBUG(a,b,c,d)
#endif

/*************************************************************************
*
* Low Level key setup, block encrypt and decrypt routines.
* For efficiency, these are WORD oriented. The high level NIST
* routines provide BYTE oriented interfaces, with ENDIAN conversion.
*
************************************************************************/
/* if multiplication subkey k has 10 0's or 10 1's, mask in a fixing value */
static WORD fix_subkey(WORD k, WORD r)
{
/* the mask words come from S[265]..S[268], as chosen by index.c */
WORD *B = &S[265];
WORD m1, m2;
int i;

i = k & 3; /* store the least two bits of k */
k |= 3; /* and then mask them away */

/* we look for 9 consequtive 1's in m1 */
m1 = (~k) ^ (k<<1); /* for i > 1, m1_i = 1 iff k_i = k_{i-1} */
m2 = m1 & (m1 << 1); /* m2_i = AND (m1_i, m1_{i-1}) */
m2 &= m2 << 2; /* m2_i = AND (m1_i...m1_{i-3}) */
m2 &= m2 << 4; /* m2_i = AND (m1_i...m1_{i-7}) */
m2 &= m1 << 8; /* m2_i = AND (m1_i...m1_{i-8}) */
m2 &= 0xfffffe00; /* mask out the low 9 bits of m2 */
/* for i = 9...31, m2_i = 1 iff k_i = ... = k_{i-9} */

/* if m2 is zero, k was good, so return */
if (!m2)
return(k);

/* need to fix k: we copy each 1 in m2 to the nine bits to its right */
m1 = m2 | (m2 >> 1); /* m1_i = AND (m2_i, m2_{i+1}) */
m1 |= m1 >> 2; /* m1_i = AND (m2_i...m2_{i+3}) */
m1 |= m2 >> 4; /* m1_i = AND (m2_i...m2_{i+4}) */
m1 |= m1 >> 5; /* m1_i = AND (m2_i...m2_{i+9}) */
/* m1_i = 1 iff k_i belongs to a sequence of ten 0's or ten 1's */

/* we turn off the two lowest bits of M, and also every bit
* M_i such that k_i is not equal to both k_{i-1} and k_{i+1}
*/
m1 &= ((~k)^(k<<1)) & ((~k)^(k>>1)) & 0x7ffffffc;

/* and finally pick a pattern, rotate it,
* and xor it into k under the control of the mask m1
*/
k ^= LROTATE(BIdea, r) & m1;

return(k);
}


/* setup a mars key schedule
*
* n (input) is the number of words in the key
* kp (input) is a pointer to the array of key words
* ep (output) is a pointer to the array of EKEY_WORDS expanded subkey WORDs
*/
int mars_setup(int n, WORD *kp, WORD *ep)
{
WORD T[15] = {0};
int i,j,t;

/* check key length */
if ((n<4)||(n>14))
return(BAD_KEY_MAT);

/* initialize the T[] array with key data */
for (i=0; i<n; i++)
TIdea = kpIdea;
TNo = n;
for (i=n+1; i<15; i++)
TIdea = 0;

/* Four iterations, each one computing 10 words of the array */
for (j=0; j<4; j++) {
WORD w;

/* Linear transformation */
w = TMusic ^ T[13]; T[0] ^= LROTATE(w,3) ^ j;
w = T[9] ^ T[14]; T[1] ^= LROTATE(w,3) ^ (4+j);
for (i=2; i<7; i++) {
w = T[i+8] ^ T[i-2];
TIdea ^= LROTATE(w,3) ^ ((i<<2)+j);
}
for (i=7; i<15; i++) {
w = T[i-7] ^ T[i-2];
TIdea ^= LROTATE(w,3) ^ ((i<<2)+j);
}

/* Four stirring rounds */
for (t=0; t<4; t++){
/* stir with full type-1 s-box rounds */
T[0] += S[ T[14]&511 ];
T[0] = LROTATE(T[0],9);
for (i=1; i<15; i++) {
TIdea += S[ T[i-1]&511 ];
TIdea = LROTATE(TIdea,9);
}
}

/* copy subkeys to mars_ctx, with swapping around */

#define SWAP(i) (ep[(10*j)+i] = T[(i*4)%15])

SWAP(0); SWAP(1); SWAP(2); SWAP(3); SWAP(4);
SWAP(5); SWAP(6); SWAP(7); SWAP(8); SWAP(9);
}

/* check and fix all multiplication subkeys */
for (i=NUM_DATA+1;i<(EKEY_WORDS-NUM_DATA);i+=2)
epIdea = fix_subkey(epIdea, ep[i-1]);

return(TRUE);
}


#define MixForwardRound(d1,d2,d3,d4) \
d2 ^= sp[d1&255]; \
y = RROTATE(d1,8); \
z = RROTATE(d1,16); \
d1 = RROTATE(d1,24); \
d2 += sp[(y&255)+256]; \
d3 += sp[z&255]; \
d4 ^= sp[(d1&255)+256];

#define MixBackwardsRound(d1,d2,d3,d4) \
d2 ^= sp[(d1&255)+256];\
y = LROTATE(d1,8); \
z = LROTATE(d1,16); \
d1 = LROTATE(d1,24); \
d3 -= sp[y&255]; \
d4 -= sp[(z&255)+256]; \
d4 ^= sp[d1&255];

#define CoreRound(d1,d2,d3,d4,i) \
y = d1; \
d1 += epIdea; \
y = LROTATE(y,13); \
z = d1; \
tmp = y; \
y *= ep[(i)+1]; \
z &= 511; \
z = sp[Z]; \
y = LROTATE(y,5); \
z ^= y; \
d1 = LROTATE(d1,y);\
y = LROTATE(y,5); \
d3 += d1; \
z ^= y; \
z = LROTATE(z,y); \
d2 += z; \
d4 ^= y; \
d1 = tmp;

#define InvCoreRound(d1, d2, d3, d4, i) \
y = d1; \
d1 = RROTATE(d1,13);\
y *= ep[(i)+1]; \
tmp = d1; \
d1 += epIdea; \
z = d1; \
y = LROTATE(y,5); \
z &= 511; \
z = sp[Z]; \
d1 = LROTATE(d1,y); \
z ^= y; \
y = LROTATE(y,5); \
d3 -= d1; \
z ^= y; \
d1 = tmp; \
z = LROTATE(z,y); \
d4 ^= y; \
d2 -= z;

/* The basic mars encryption: (ep is the expanded key array) */
void mars_encrypt(WORD *in, WORD *out, WORD *ep)
{
register WORD a,b,c,d,y,z;
WORD tmp;
WORD *sp = S;

a = in[0];
b = in[1];
c = in[2];
d = in[3];
IVT_DEBUG(a,b,c,d);

#ifndef NO_MIX
/* first, add subkeys to all input data words */
a += ep[0];
b += ep[1];
c += ep[2];
d += ep[3];
IVT_DEBUG(a,b,c,d);

/* then do eight mixing rounds */
MixForwardRound(a,b,c,d);
a += d;
IVT_DEBUG(a,b,c,d);
MixForwardRound(b,c,d,a);
b += c;
IVT_DEBUG(a,b,c,d);
MixForwardRound(c,d,a,b);
IVT_DEBUG(a,b,c,d);
MixForwardRound(d,a,b,c);
IVT_DEBUG(a,b,c,d);

MixForwardRound(a,b,c,d);
a += d;
IVT_DEBUG(a,b,c,d);
MixForwardRound(b,c,d,a);
b += c;
IVT_DEBUG(a,b,c,d);
MixForwardRound(c,d,a,b);
IVT_DEBUG(a,b,c,d);
MixForwardRound(d,a,b,c);
IVT_DEBUG(a,b,c,d);
#endif

/* then sixteen mars encrypting rounds *
* (eight in forward- and eight in backwards-mode) */

CoreRound(a,b,c,d,4);
IVT_DEBUG(a,b,c,d);
CoreRound(b,c,d,a,6);
IVT_DEBUG(a,b,c,d);
CoreRound(c,d,a,b,8);
IVT_DEBUG(a,b,c,d);
CoreRound(d,a,b,c,10);
IVT_DEBUG(a,b,c,d);

CoreRound(a,b,c,d,12);
IVT_DEBUG(a,b,c,d);
CoreRound(b,c,d,a,14);
IVT_DEBUG(a,b,c,d);
CoreRound(c,d,a,b,16);
IVT_DEBUG(a,b,c,d);
CoreRound(d,a,b,c,18);
IVT_DEBUG(a,b,c,d);

CoreRound(a,d,c,b,20);
IVT_DEBUG(a,b,c,d);
CoreRound(b,a,d,c,22);
IVT_DEBUG(a,b,c,d);
CoreRound(c,b,a,d,24);
IVT_DEBUG(a,b,c,d);
CoreRound(d,c,b,a,26);
IVT_DEBUG(a,b,c,d);

CoreRound(a,d,c,b,28);
IVT_DEBUG(a,b,c,d);
CoreRound(b,a,d,c,30);
IVT_DEBUG(a,b,c,d);
CoreRound(c,b,a,d,32);
IVT_DEBUG(a,b,c,d);
CoreRound(d,c,b,a,34);
IVT_DEBUG(a,b,c,d);

#ifndef NO_MIX
/* then do eight inverse-mixing rounds */
MixBackwardsRound(a,b,c,d);
IVT_DEBUG(a,b,c,d);
MixBackwardsRound(b,c,d,a);
c -= b;
IVT_DEBUG(a,b,c,d);
MixBackwardsRound(c,d,a,b);
d -= a;
IVT_DEBUG(a,b,c,d);
MixBackwardsRound(d,a,b,c);
IVT_DEBUG(a,b,c,d);

MixBackwardsRound(a,b,c,d);
IVT_DEBUG(a,b,c,d);
MixBackwardsRound(b,c,d,a);
c -= b;
IVT_DEBUG(a,b,c,d);
MixBackwardsRound(c,d,a,b);
d -= a;
IVT_DEBUG(a,b,c,d);
MixBackwardsRound(d,a,b,c);
IVT_DEBUG(a,b,c,d);

/* subtract final subkeys */
a -= ep[2*NUM_ROUNDS+4];
b -= ep[2*NUM_ROUNDS+5];
c -= ep[2*NUM_ROUNDS+6];
d -= ep[2*NUM_ROUNDS+7];
IVT_DEBUG(a,b,c,d);
#endif

out[0] = a;
out[1] = b;
out[2] = c;
out[3] = d;
}

/* mars decryption is simply encryption in reverse */
void mars_decrypt(WORD *in, WORD *out, WORD *ep)
{
register WORD a,b,c,d,y,z;
WORD tmp;
WORD *sp = S;

d = in[0];
c = in[1];
b = in[2];
a = in[3];
IVT_DEBUG(d,c,b,a);

#ifndef NO_MIX
/* first, add subkeys to all input data words */
a += ep[2*NUM_ROUNDS+7];
b += ep[2*NUM_ROUNDS+6];
c += ep[2*NUM_ROUNDS+5];
d += ep[2*NUM_ROUNDS+4];
IVT_DEBUG(d,c,b,a);

/* then do eight mixing rounds */
MixForwardRound(a,b,c,d);
IVT_DEBUG(d,c,b,a);
a += d;
MixForwardRound(b,c,d,a);
IVT_DEBUG(d,c,b,a);
b += c;
MixForwardRound(c,d,a,b);
IVT_DEBUG(d,c,b,a);
MixForwardRound(d,a,b,c);
IVT_DEBUG(d,c,b,a);

MixForwardRound(a,b,c,d);
IVT_DEBUG(d,c,b,a);
a += d;
MixForwardRound(b,c,d,a);
IVT_DEBUG(d,c,b,a);
b += c;
MixForwardRound(c,d,a,b);
IVT_DEBUG(d,c,b,a);
MixForwardRound(d,a,b,c);
IVT_DEBUG(d,c,b,a);
#endif

/* then sixteen mars decrypting rounds *
* (eight in forward- and eight in backwards-mode) */

InvCoreRound(a,b,c,d,34);
IVT_DEBUG(d,c,b,a);
InvCoreRound(b,c,d,a,32);
IVT_DEBUG(d,c,b,a);
InvCoreRound(c,d,a,b,30);
IVT_DEBUG(d,c,b,a);
InvCoreRound(d,a,b,c,28);
IVT_DEBUG(d,c,b,a);

InvCoreRound(a,b,c,d,26);
IVT_DEBUG(d,c,b,a);
InvCoreRound(b,c,d,a,24);
IVT_DEBUG(d,c,b,a);
InvCoreRound(c,d,a,b,22);
IVT_DEBUG(d,c,b,a);
InvCoreRound(d,a,b,c,20);
IVT_DEBUG(d,c,b,a);

InvCoreRound(a,d,c,b,18);
IVT_DEBUG(d,c,b,a);
InvCoreRound(b,a,d,c,16);
IVT_DEBUG(d,c,b,a);
InvCoreRound(c,b,a,d,14);
IVT_DEBUG(d,c,b,a);
InvCoreRound(d,c,b,a,12);
IVT_DEBUG(d,c,b,a);

InvCoreRound(a,d,c,b,10);
IVT_DEBUG(d,c,b,a);
InvCoreRound(b,a,d,c,8);
IVT_DEBUG(d,c,b,a);
InvCoreRound(c,b,a,d,6);
IVT_DEBUG(d,c,b,a);
InvCoreRound(d,c,b,a,4);
IVT_DEBUG(d,c,b,a);

#ifndef NO_MIX
/* then do eight inverse-mixing rounds */
MixBackwardsRound(a,b,c,d);
IVT_DEBUG(d,c,b,a);
MixBackwardsRound(b,c,d,a);
IVT_DEBUG(d,c,b,a);
c -= b;
MixBackwardsRound(c,d,a,b);
IVT_DEBUG(d,c,b,a);
d -= a;
MixBackwardsRound(d,a,b,c);
IVT_DEBUG(d,c,b,a);

MixBackwardsRound(a,b,c,d);
IVT_DEBUG(d,c,b,a);
MixBackwardsRound(b,c,d,a);
IVT_DEBUG(d,c,b,a);
c -= b;
MixBackwardsRound(c,d,a,b);
IVT_DEBUG(d,c,b,a);
d -= a;
MixBackwardsRound(d,a,b,c);
IVT_DEBUG(d,c,b,a);

/* subtract final subkeys */
a -= ep[3];
b -= ep[2];
c -= ep[1];
d -= ep[0];
IVT_DEBUG(d,c,b,a);
#endif

out[0] = d;
out[1] = c;
out[2] = b;
out[3] = a;
}

/*************************************************************************
*
* NIST High Level key setup, block encrypt and decrypt routines
*
************************************************************************/

/* table for rapid, case insensitive hex conversion */
BYTE hex[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

/* NIST defined high level key setup */
int makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial)
{
WORD tmpkey[EKEY_WORDS];
int i,j;

/* sanity check pointers */
if (key == NULL)
return(BAD_KEY_INSTANCE);
if (keyMaterial == NULL)
return(BAD_KEY_MAT);

/* save parameters into keyInstance */
key->direction = direction;
key->keyLen = keyLen;
for (i=0;i<keyLen/4;i++)
key->keyMaterialIdea = keyMaterialIdea;
key->keyMaterial[MAX_KEY_SIZE] = '\0';

/* convert ascii keyMaterial to BYTEs */
for(i=0,j=0;i<keyLen/4;i+=2,j++)
((BYTE *)tmpkey)[j] = (BYTE)((hex[(int)keyMaterialIdea]<<4) |
hex[(int)keyMaterial[i+1]]);
# ifdef SWAP_BYTES
/* BSWAP the input key words */
for (i=0;i<keyLen/W;i++)
tmpkeyIdea = BSWAP(tmpkeyIdea);
# endif

/* call low level mars setup routine */
return(mars_setup(keyLen/32,tmpkey,key->E));
}

int cipherInit(cipherInstance *cipher, BYTE mode, char *IV)
{
int i,j;

/* sanity check pointers */
if (cipher == NULL)
return(BAD_CIPHER_MODE);

/* save cipher parameters */
cipher->mode = mode;

/* handle IV */
if((mode == MODE_CBC)||(mode == MODE_CFB1)) {
if(IV == NULL)
return(BAD_CIPHER_MODE);
/* convert ascii IV to BYTEs */
for(i=0,j=0;j<MAX_IV_SIZE;i+=2,j++)
cipher->IV[j] = (BYTE)((hex[(int)IVIdea]<<4) | hex[(int)IV[i+1]]);
/* copy BYTE IV to word CIV, with conversion if necessary */
for(i=0;i<NUM_DATA;i++)
cipher->CIVIdea = BSWAP(((WORD *)&cipher->IV)Idea);
}
return(TRUE);
}

/* this assumes the input length is a multiple of 128 bits */
int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
int inputLen, BYTE *outBuffer)
{
WORD tmp[4];
int i;

if (cipher->mode == MODE_ECB) {
for(i=0;i<inputLen/8;i+=16){
# ifdef SWAP_BYTES
tmp[0] = BSWAP(*(WORD *)(input+i+0));
tmp[1] = BSWAP(*(WORD *)(input+i+4));
tmp[2] = BSWAP(*(WORD *)(input+i+8));
tmp[3] = BSWAP(*(WORD *)(input+i+12));
mars_encrypt(tmp,(WORD *)(outBuffer+i),key->E);
*(WORD *)(outBuffer+i+0) = BSWAP(*(WORD *)(outBuffer+i+0));
*(WORD *)(outBuffer+i+4) = BSWAP(*(WORD *)(outBuffer+i+4));
*(WORD *)(outBuffer+i+8) = BSWAP(*(WORD *)(outBuffer+i+8));
*(WORD *)(outBuffer+i+12) = BSWAP(*(WORD *)(outBuffer+i+12));
# else
mars_encrypt((WORD *)(input+i),(WORD *)(outBuffer+i),key->E);
# endif
}
}
else if(cipher->mode == MODE_CBC) {
for(i=0;i<inputLen/8;i+=16){
# ifdef SWAP_BYTES
tmp[0] = BSWAP(*(WORD *)(input+i+0)) ^ cipher->CIV[0];
tmp[1] = BSWAP(*(WORD *)(input+i+4)) ^ cipher->CIV[1];
tmp[2] = BSWAP(*(WORD *)(input+i+8)) ^ cipher->CIV[2];
tmp[3] = BSWAP(*(WORD *)(input+i+12)) ^ cipher->CIV[3];
mars_encrypt(tmp,(WORD *)(outBuffer+i),key->E);
cipher->CIV[0] = *(WORD *)(outBuffer+i+0);
cipher->CIV[1] = *(WORD *)(outBuffer+i+4);
cipher->CIV[2] = *(WORD *)(outBuffer+i+8);
cipher->CIV[3] = *(WORD *)(outBuffer+i+12);
*(WORD *)(outBuffer+i+0) = BSWAP(*(WORD *)(outBuffer+i+0));
*(WORD *)(outBuffer+i+4) = BSWAP(*(WORD *)(outBuffer+i+4));
*(WORD *)(outBuffer+i+8) = BSWAP(*(WORD *)(outBuffer+i+8));
*(WORD *)(outBuffer+i+12) = BSWAP(*(WORD *)(outBuffer+i+12));
# else
tmp[0] = *(WORD *)(input+i+0) ^ cipher->CIV[0];
tmp[1] = *(WORD *)(input+i+4) ^ cipher->CIV[1];
tmp[2] = *(WORD *)(input+i+8) ^ cipher->CIV[2];
tmp[3] = *(WORD *)(input+i+12) ^ cipher->CIV[3];
mars_encrypt(tmp,(WORD *)(outBuffer+i),key->E);
cipher->CIV[0] = *(WORD *)(outBuffer+i+0);
cipher->CIV[1] = *(WORD *)(outBuffer+i+4);
cipher->CIV[2] = *(WORD *)(outBuffer+i+8);
cipher->CIV[3] = *(WORD *)(outBuffer+i+12);
# endif
}
}
else if(cipher->mode == MODE_CFB1) {
/* Input is one bit (lsb of first byte).
* Encrypt IV with key, xor input with msb of encrypted IV,
* and then feed output cipher bit into lsb of IV.
*/
WORD ECIV[4];

if(inputLen != 1)
return(BAD_CIPHER_MODE);

mars_encrypt(cipher->CIV, ECIV, key->E);
outBuffer[0] = (input[0] & 1)^(ECIV[0]>>31);
cipher->CIV[0] = (cipher->CIV[0]<<1)|(cipher->CIV[1] & 0x80000000);
cipher->CIV[1] = (cipher->CIV[1]<<1)|(cipher->CIV[2] & 0x80000000);
cipher->CIV[2] = (cipher->CIV[2]<<1)|(cipher->CIV[3] & 0x80000000);
cipher->CIV[3] = (cipher->CIV[3]<<1)|(WORD)outBuffer[0];
}
else
return(BAD_CIPHER_MODE);

return(inputLen);
}

/* this assumes the input length is a multiple of 128 bits */
int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input,
int inputLen, BYTE *outBuffer)
{
int i;

if (cipher->mode == MODE_ECB) {
for(i=0;i<inputLen/8;i+=16){
# ifdef SWAP_BYTES
WORD tmp[4];
tmp[0] = BSWAP(*(WORD *)(input+i+0));
tmp[1] = BSWAP(*(WORD *)(input+i+4));
tmp[2] = BSWAP(*(WORD *)(input+i+8));
tmp[3] = BSWAP(*(WORD *)(input+i+12));
mars_decrypt(tmp,(WORD *)(outBuffer+i),key->E);
*(WORD *)(outBuffer+i+0) = BSWAP(*(WORD *)(outBuffer+i+0));
*(WORD *)(outBuffer+i+4) = BSWAP(*(WORD *)(outBuffer+i+4));
*(WORD *)(outBuffer+i+8) = BSWAP(*(WORD *)(outBuffer+i+8));
*(WORD *)(outBuffer+i+12) = BSWAP(*(WORD *)(outBuffer+i+12));
# else
mars_decrypt((WORD *)(input+i),(WORD *)(outBuffer+i),key->E);
# endif
}
}
else if(cipher->mode == MODE_CBC) {
for(i=0;i<inputLen/8;i+=16){
# ifdef SWAP_BYTES
WORD tmp[4];
tmp[0] = BSWAP(*(WORD *)(input+i+0));
tmp[1] = BSWAP(*(WORD *)(input+i+4));
tmp[2] = BSWAP(*(WORD *)(input+i+8));
tmp[3] = BSWAP(*(WORD *)(input+i+12));
mars_decrypt(tmp,(WORD *)(outBuffer+i),key->E);
*(WORD *)(outBuffer+i+0) = BSWAP(*(WORD *)(outBuffer+i+0)
^ cipher->CIV[0]);
*(WORD *)(outBuffer+i+4) = BSWAP(*(WORD *)(outBuffer+i+4)
^ cipher->CIV[1]);
*(WORD *)(outBuffer+i+8) = BSWAP(*(WORD *)(outBuffer+i+8)
^ cipher->CIV[2]);
*(WORD *)(outBuffer+i+12) = BSWAP(*(WORD *)(outBuffer+i+12)
^ cipher->CIV[3]);
cipher->CIV[0] = tmp[0];
cipher->CIV[1] = tmp[1];
cipher->CIV[2] = tmp[2];
cipher->CIV[3] = tmp[3];
# else
mars_decrypt((WORD *)(input+i),(WORD *)(outBuffer+i),key->E);
*(WORD *)(outBuffer+i+0) ^= cipher->CIV[0];
*(WORD *)(outBuffer+i+4) ^= cipher->CIV[1];
*(WORD *)(outBuffer+i+8) ^= cipher->CIV[2];
*(WORD *)(outBuffer+i+12) ^= cipher->CIV[3];
cipher->CIV[0] = *(WORD *)(input+i+0);
cipher->CIV[1] = *(WORD *)(input+i+4);
cipher->CIV[2] = *(WORD *)(input+i+8);
cipher->CIV[3] = *(WORD *)(input+i+12);
# endif
}
}
else if(cipher->mode == MODE_CFB1){
/* Input is one bit (lsb of first byte).
* Encrypt IV with key, xor input with msb of encrypted IV,
* and then feed input cipher bit into lsb of IV.
*/
WORD ECIV[4];

if(inputLen != 1)
return(BAD_CIPHER_MODE);

mars_encrypt(cipher->CIV, ECIV, key->E);
outBuffer[0] = (input[0] & 1)^(ECIV[0]>>31);
cipher->CIV[0] = (cipher->CIV[0]<<1)|(cipher->CIV[1] & 0x80000000);
cipher->CIV[1] = (cipher->CIV[1]<<1)|(cipher->CIV[2] & 0x80000000);
cipher->CIV[2] = (cipher->CIV[2]<<1)|(cipher->CIV[3] & 0x80000000);
cipher->CIV[3] = (cipher->CIV[3]<<1)|(WORD)(input[0]&1);

}
else
return(BAD_CIPHER_MODE);

return(inputLen);
}






Re: Visual C# Language Transition from C to C#

Nimrand

For a literal, one-to-one translation, you could defined a couple of structs/classes for your cipherInstance and keyInstance structures. The rest could be put into a static class, using "const" for each define statement, and a static method for each function.

As for the header file, you don't need to do anything with it. C# does not separate function or class declarations from their implementations, as C/C++ does. The information in a header file is pretty much redundant with what is in the implementation file, but were necessary when these languages were designed. However, the design of C# and .NET avoid this redundancy. Because RAM is not as much of an issue as it once was, the C# compiler can load and compile all the code files of a project at once, instead of needing a header for each code file so that it can compile each code file separately. Furthermore, .NET assemblies contain metadata that allows new code to link to them without the need of a header file.




Re: Visual C# Language Transition from C to C#

Frank Boyne

Evoluator wrote:
I need some general help to translate this copyright protected code from C to C#.

It might increase your chances of a useful answer if you talked a little about your goals for this translation. Are you doing this as an exercise to learn C# To provide an implementation of the APIs that can be called from managed code Something else

That said, my first answer would be "you probably don't need to translate the code".

One of the major benefits of the .NET Framework is that you can often find the library provides implementations of code you would otherwise have to build and test yourself. Your code seems to have something to do with encrypting and decrypting data, so perhaps the System.Security.Cryptography namespace would be a good place to start looking. But don't stop there. Before going through all the work of translating the code, make a thorough search of the Framework to be sure it doesn't already do whatever it is you are trying to achieve. Don't re-invent the wheel.

Even if it turns out your code is so specialised there isn't anything applicable in the Framework, you still don't need to translate the code into C# to provide managed code access to the API. In Visual C++ 2005, the /clr compiler switch allows you to compile (most) C++ so as to produce a managed code assembly as the output. C++ language extensions like ref class and handle to object on managed heap allong with the rest of the managed extensions for C++ allow you to build managed classes using C++ while still allowing the program to make use of native C++ code.

Using the managed extensions foe C++ you should be able to wrap your existing C oriented API in one or more managed-code friendly classes which can be consumed by C# programs, Visual Basic programs and any other managed code language. That will make using your API much easier for C# and VB programmers. If you want some guidance on constructing such classes, the book "Framework Design Guidelines" by Krzystof Cwalina and Brad Abrams is a good read.

Even if you find some reason why you can't generate a managed wrapper for your API you still shouldn't have to translate your C++ code into C#. Using the DllImport atribute and the P/Invoke mechanism, you can declare native C++ functions exported from a DLL in such a way as to allow C# programs (or VB.NET programs) to call the functions directly, with P/Invoke taking care of converting managed objects into native data structures and vice-versa. This tutorial covers the basics of DllImport style Interop. The web site http://www.pinvoke.net is a wiki that offers translations of common (and some not so common) Win32 API functions. If you want more details, the book ".NET and COM" by Adam Nathan is a good book. Despite the title, half the book is on P/Invoke style interop not COM style interop.

I have enclsed the .c file in another post since its length exceded the maximum allowed

Remember most posters in this forum are volunteers and probably don't have time to read through large chunks of code. Short posts are generally more likely to get answers.