source: trunk/NativeCryptography/NativeCryptography.cpp @ 1197

Last change on this file since 1197 was 1197, checked in by Sven Rech, 12 years ago

implemented CFB properly

File size: 3.2 KB
Line 
1// This is the main DLL file.
2
3#include "NativeCryptography.h"
4
5namespace NativeCryptography {
6
7        /* Fast way to xor an AES block */
8        void Crypto::xorBlockAES(int *t1, int *t2)
9        {
10                t1[0] ^= t2[0];
11                t1[1] ^= t2[1];
12                t1[2] ^= t2[2];
13                t1[3] ^= t2[3];
14        }
15
16        /* Fast way to xor an DES block */
17        void Crypto::xorBlockDES(int *t1, int *t2)
18        {
19                t1[0] ^= t2[0];
20                t1[1] ^= t2[1];
21        }
22
23        void Crypto::encrypt(unsigned char* in, unsigned char* out, const cryptMethod method, AES_KEY* aeskey, DES_key_schedule* deskey)
24        {
25                if (method == cryptMethod::methodAES)
26                        AES_encrypt(in, out, aeskey);
27                else
28                        DES_ecb_encrypt((const_DES_cblock*)in, (const_DES_cblock*)out, deskey, DES_ENCRYPT);
29        }
30
31        void Crypto::decrypt(unsigned char* in, unsigned char* out, const cryptMethod method, AES_KEY* aeskey, DES_key_schedule* deskey)
32        {
33                if (method == cryptMethod::methodAES)
34                        AES_decrypt(in, out, aeskey);
35                else
36                        DES_ecb_encrypt((const_DES_cblock*)in, (const_DES_cblock*)out, deskey, DES_DECRYPT);
37        }
38
39
40        void Crypto::xorblock(unsigned char* t1, unsigned char* t2, const cryptMethod method) {
41                if (method == cryptMethod::methodAES)
42                        xorBlockAES((int*)t1, (int*)t2);
43                else
44                        xorBlockDES((int*)t1, (int*)t2); 
45        }
46
47        array<unsigned char>^ Crypto::decryptAESorDES(array<unsigned char>^ Input, array<unsigned char>^ Key, array<unsigned char>^ IV, const int bits, const int length, const int mode, const int blockSize, const cryptMethod method)
48        {
49                int numBlocks = length / blockSize;
50                if (length % blockSize != 0)
51                        numBlocks++;
52
53                if (IV == nullptr)
54                        IV = gcnew array<unsigned char>(blockSize);
55
56                pin_ptr<unsigned char> input = &Input[0];
57                pin_ptr<unsigned char> key = &Key[0];
58                pin_ptr<unsigned char> iv = &IV[0];
59
60                array<unsigned char>^ output = gcnew array<unsigned char>(length);
61                pin_ptr<unsigned char> outp = &output[0];       
62
63                AES_KEY aeskey;
64                DES_key_schedule deskey;
65                if (mode == 2)  //CFB
66                {
67                        array<unsigned char>^ ShiftRegister = (array<unsigned char>^)IV->Clone();
68                        pin_ptr<unsigned char> shiftregister = &ShiftRegister[0];                       
69                        unsigned char block[16];        //16 is enough for AES and DES
70
71                        if (method == cryptMethod::methodAES) 
72                                AES_set_encrypt_key(key, bits, &aeskey);
73                        else 
74                                DES_set_key_unchecked((const_DES_cblock*)key, &deskey);
75
76                        for (int i = 0; i < length; i++)
77                        {
78                                encrypt(shiftregister, block, method, &aeskey, &deskey);
79                                unsigned char leftmost = block[0];
80                                outp[i] = leftmost ^ input[i];
81                               
82                                //shift input[i] in register:
83                                for (int c = 0; c < blockSize - 1; c++)
84                                        shiftregister[c] = shiftregister[c+1];
85                                shiftregister[blockSize-1] = input[i];
86                        }
87                }
88                else    //CBC or ECB
89                {
90                        if (method == cryptMethod::methodAES)
91                                AES_set_decrypt_key(key, bits, &aeskey);
92                        else
93                                DES_set_key_unchecked((const_DES_cblock*)key, &deskey);
94
95                        decrypt(input, outp, method, &aeskey, &deskey);                         
96                        if (mode == 1)          //CBC
97                                xorblock(outp, iv, method);     
98                        for (int c = 1; c < numBlocks; c++)
99                        {
100                                decrypt(input+c*blockSize, outp+c*blockSize, method, &aeskey, &deskey);
101                                if (mode == 1)          //CBC
102                                        xorblock(outp+c*blockSize, input+(c-1)*blockSize, method);                             
103                        }
104                }
105
106                return output;
107        }
108
109}
Note: See TracBrowser for help on using the repository browser.