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