Mercurial > dropbear
comparison s_ocb_done.c @ 0:d7da3b1e1540 libtomcrypt
put back the 0.95 makefile which was inadvertently merged over
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 31 May 2004 18:21:40 +0000 |
parents | |
children | 5d99163f7e32 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d7da3b1e1540 |
---|---|
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 /* Since the last block is encrypted in CTR mode the same code can | |
18 * be used to finish a decrypt or encrypt stream. The only difference | |
19 * is we XOR the final ciphertext into the checksum so we have to xor it | |
20 * before we CTR [decrypt] or after [encrypt] | |
21 * | |
22 * the names pt/ptlen/ct really just mean in/inlen/out but this is the way I wrote it... | |
23 */ | |
24 int __ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, | |
25 unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode) | |
26 | |
27 { | |
28 unsigned char Z[MAXBLOCKSIZE], Y[MAXBLOCKSIZE], X[MAXBLOCKSIZE]; | |
29 int err, x; | |
30 | |
31 _ARGCHK(ocb != NULL); | |
32 _ARGCHK(pt != NULL); | |
33 _ARGCHK(ct != NULL); | |
34 _ARGCHK(tag != NULL); | |
35 _ARGCHK(taglen != NULL); | |
36 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { | |
37 return err; | |
38 } | |
39 if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length || | |
40 (int)ptlen > ocb->block_len || (int)ptlen < 0) { | |
41 return CRYPT_INVALID_ARG; | |
42 } | |
43 | |
44 /* compute X[m] = len(pt[m]) XOR Lr XOR Z[m] */ | |
45 ocb_shift_xor(ocb, X); | |
46 memcpy(Z, X, ocb->block_len); | |
47 | |
48 X[ocb->block_len-1] ^= (ptlen*8)&255; | |
49 X[ocb->block_len-2] ^= ((ptlen*8)>>8)&255; | |
50 for (x = 0; x < ocb->block_len; x++) { | |
51 X[x] ^= ocb->Lr[x]; | |
52 } | |
53 | |
54 /* Y[m] = E(X[m])) */ | |
55 cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key); | |
56 | |
57 if (mode == 1) { | |
58 /* decrypt mode, so let's xor it first */ | |
59 /* xor C[m] into checksum */ | |
60 for (x = 0; x < (int)ptlen; x++) { | |
61 ocb->checksum[x] ^= ct[x]; | |
62 } | |
63 } | |
64 | |
65 /* C[m] = P[m] xor Y[m] */ | |
66 for (x = 0; x < (int)ptlen; x++) { | |
67 ct[x] = pt[x] ^ Y[x]; | |
68 } | |
69 | |
70 if (mode == 0) { | |
71 /* encrypt mode */ | |
72 /* xor C[m] into checksum */ | |
73 for (x = 0; x < (int)ptlen; x++) { | |
74 ocb->checksum[x] ^= ct[x]; | |
75 } | |
76 } | |
77 | |
78 /* xor Y[m] and Z[m] into checksum */ | |
79 for (x = 0; x < ocb->block_len; x++) { | |
80 ocb->checksum[x] ^= Y[x] ^ Z[x]; | |
81 } | |
82 | |
83 /* encrypt checksum, er... tag!! */ | |
84 cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key); | |
85 | |
86 /* now store it */ | |
87 for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) { | |
88 tag[x] = X[x]; | |
89 } | |
90 *taglen = x; | |
91 | |
92 #ifdef CLEAN_STACK | |
93 zeromem(X, sizeof(X)); | |
94 zeromem(Y, sizeof(Y)); | |
95 zeromem(Z, sizeof(Z)); | |
96 zeromem(ocb, sizeof(*ocb)); | |
97 #endif | |
98 return CRYPT_OK; | |
99 } | |
100 | |
101 #endif | |
102 |