Mercurial > dropbear
comparison ocb_init.c @ 3:7faae8f46238 libtomcrypt-orig
Branch renaming
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 31 May 2004 18:25:41 +0000 |
parents | |
children | 5d99163f7e32 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 3:7faae8f46238 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.org | |
10 */ | |
11 | |
12 /* OCB Implementation by Tom St Denis */ | |
13 #include "mycrypt.h" | |
14 | |
15 #ifdef OCB_MODE | |
16 | |
17 static const struct { | |
18 int len; | |
19 unsigned char poly_div[MAXBLOCKSIZE], | |
20 poly_mul[MAXBLOCKSIZE]; | |
21 } polys[] = { | |
22 { | |
23 8, | |
24 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, | |
25 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } | |
26 }, { | |
27 16, | |
28 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, | |
30 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } | |
32 } | |
33 }; | |
34 | |
35 int ocb_init(ocb_state *ocb, int cipher, | |
36 const unsigned char *key, unsigned long keylen, const unsigned char *nonce) | |
37 { | |
38 int poly, x, y, m, err; | |
39 | |
40 _ARGCHK(ocb != NULL); | |
41 _ARGCHK(key != NULL); | |
42 _ARGCHK(nonce != NULL); | |
43 | |
44 /* valid cipher? */ | |
45 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { | |
46 return err; | |
47 } | |
48 | |
49 /* determine which polys to use */ | |
50 ocb->block_len = cipher_descriptor[cipher].block_length; | |
51 for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { | |
52 if (polys[poly].len == ocb->block_len) { | |
53 break; | |
54 } | |
55 } | |
56 if (polys[poly].len != ocb->block_len) { | |
57 return CRYPT_INVALID_ARG; | |
58 } | |
59 | |
60 /* schedule the key */ | |
61 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { | |
62 return err; | |
63 } | |
64 | |
65 /* find L = E[0] */ | |
66 zeromem(ocb->L, ocb->block_len); | |
67 cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key); | |
68 | |
69 /* find R = E[N xor L] */ | |
70 for (x = 0; x < ocb->block_len; x++) { | |
71 ocb->R[x] = ocb->L[x] ^ nonce[x]; | |
72 } | |
73 cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key); | |
74 | |
75 /* find Ls[i] = L << i for i == 0..31 */ | |
76 memcpy(ocb->Ls[0], ocb->L, ocb->block_len); | |
77 for (x = 1; x < 32; x++) { | |
78 m = ocb->Ls[x-1][0] >> 7; | |
79 for (y = 0; y < ocb->block_len-1; y++) { | |
80 ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255; | |
81 } | |
82 ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255; | |
83 | |
84 if (m == 1) { | |
85 for (y = 0; y < ocb->block_len; y++) { | |
86 ocb->Ls[x][y] ^= polys[poly].poly_mul[y]; | |
87 } | |
88 } | |
89 } | |
90 | |
91 /* find Lr = L / x */ | |
92 m = ocb->L[ocb->block_len-1] & 1; | |
93 | |
94 /* shift right */ | |
95 for (x = ocb->block_len - 1; x > 0; x--) { | |
96 ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255; | |
97 } | |
98 ocb->Lr[0] = ocb->L[0] >> 1; | |
99 | |
100 if (m == 1) { | |
101 for (x = 0; x < ocb->block_len; x++) { | |
102 ocb->Lr[x] ^= polys[poly].poly_div[x]; | |
103 } | |
104 } | |
105 | |
106 /* set Li, checksum */ | |
107 zeromem(ocb->Li, ocb->block_len); | |
108 zeromem(ocb->checksum, ocb->block_len); | |
109 | |
110 /* set other params */ | |
111 ocb->block_index = 1; | |
112 ocb->cipher = cipher; | |
113 | |
114 return CRYPT_OK; | |
115 } | |
116 | |
117 #endif |