www.usr.com/support/gpl/USR9107_release.1.4.tar.gz
[bcm963xx.git] / userapps / opensource / sshd / libtomcrypt / cbc.c
1 #include "mycrypt.h"
2
3 #ifdef CBC
4
5 int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, 
6               int keylen, int num_rounds, symmetric_CBC *cbc)
7 {
8    int x, err;
9  
10    _ARGCHK(IV != NULL);
11    _ARGCHK(key != NULL);
12    _ARGCHK(cbc != NULL);
13
14    /* bad param? */
15    if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
16       return err;
17    }
18
19    /* setup cipher */
20    if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) {
21       return err;
22    }
23
24    /* copy IV */
25    cbc->blocklen = cipher_descriptor[cipher].block_length;
26    cbc->cipher   = cipher;
27    for (x = 0; x < cbc->blocklen; x++) {
28        cbc->IV[x] = IV[x];
29    }
30    return CRYPT_OK;
31 }
32
33 int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc)
34 {
35    int x, err;
36    unsigned char tmp[MAXBLOCKSIZE];
37
38    _ARGCHK(pt != NULL);
39    _ARGCHK(ct != NULL);
40    _ARGCHK(cbc != NULL);
41
42    if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
43        return err;
44    }
45    
46    /* is blocklen valid? */
47    if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) {
48       return CRYPT_INVALID_ARG;
49    }    
50
51    /* xor IV against plaintext */
52    for (x = 0; x < cbc->blocklen; x++) {
53        tmp[x] = pt[x] ^ cbc->IV[x];
54    }
55
56    /* encrypt */
57    cipher_descriptor[cbc->cipher].ecb_encrypt(tmp, ct, &cbc->key);
58
59    /* store IV [ciphertext] for a future block */
60    for (x = 0; x < cbc->blocklen; x++) {
61        cbc->IV[x] = ct[x];
62    }
63
64    #ifdef CLEAN_STACK
65       zeromem(tmp, sizeof(tmp));
66    #endif
67    return CRYPT_OK;
68 }
69
70 int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc)
71 {
72    int x, err;
73    unsigned char tmp[MAXBLOCKSIZE], tmp2[MAXBLOCKSIZE];
74
75    _ARGCHK(pt != NULL);
76    _ARGCHK(ct != NULL);
77    _ARGCHK(cbc != NULL);
78
79    /* decrypt the block from ct into tmp */
80    if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
81        return err;
82    }
83    cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
84    
85    /* is blocklen valid? */
86    if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) {
87       return CRYPT_INVALID_ARG;
88    } 
89
90    /* xor IV against the plaintext of the previous step */
91    for (x = 0; x < cbc->blocklen; x++) { 
92        /* copy CT in case ct == pt */
93        tmp2[x] = ct[x]; 
94
95        /* actually decrypt the byte */
96        pt[x] = tmp[x] ^ cbc->IV[x]; 
97    }
98
99    /* replace IV with this current ciphertext */ 
100    for (x = 0; x < cbc->blocklen; x++) {
101        cbc->IV[x] = tmp2[x];
102    }
103    #ifdef CLEAN_STACK
104       zeromem(tmp, sizeof(tmp));
105       zeromem(tmp2, sizeof(tmp2));
106    #endif
107    return CRYPT_OK;
108 }
109
110 #endif
111