annotate s_ocb_done.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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3 * LibTomCrypt is a library that provides various cryptographic
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 * algorithms in a highly modular and flexible manner.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6 * The library is free for all purposes without any express
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
7 * guarantee it works.
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
9 * Tom St Denis, [email protected], http://libtomcrypt.org
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
11
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12 /* OCB Implementation by Tom St Denis */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 #include "mycrypt.h"
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15 #ifdef OCB_MODE
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17 /* Since the last block is encrypted in CTR mode the same code can
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18 * be used to finish a decrypt or encrypt stream. The only difference
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19 * is we XOR the final ciphertext into the checksum so we have to xor it
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20 * before we CTR [decrypt] or after [encrypt]
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21 *
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
22 * the names pt/ptlen/ct really just mean in/inlen/out but this is the way I wrote it...
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
23 */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
24 int __ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
25 unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode)
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
26
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
27 {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28 unsigned char Z[MAXBLOCKSIZE], Y[MAXBLOCKSIZE], X[MAXBLOCKSIZE];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29 int err, x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31 _ARGCHK(ocb != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32 _ARGCHK(pt != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 _ARGCHK(ct != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34 _ARGCHK(tag != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 _ARGCHK(taglen != NULL);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
36 if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37 return err;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
38 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
39 if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length ||
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40 (int)ptlen > ocb->block_len || (int)ptlen < 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
41 return CRYPT_INVALID_ARG;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
42 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
43
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
44 /* compute X[m] = len(pt[m]) XOR Lr XOR Z[m] */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
45 ocb_shift_xor(ocb, X);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
46 memcpy(Z, X, ocb->block_len);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
47
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
48 X[ocb->block_len-1] ^= (ptlen*8)&255;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
49 X[ocb->block_len-2] ^= ((ptlen*8)>>8)&255;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
50 for (x = 0; x < ocb->block_len; x++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
51 X[x] ^= ocb->Lr[x];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
52 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
53
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
54 /* Y[m] = E(X[m])) */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
55 cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
56
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
57 if (mode == 1) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
58 /* decrypt mode, so let's xor it first */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
59 /* xor C[m] into checksum */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
60 for (x = 0; x < (int)ptlen; x++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
61 ocb->checksum[x] ^= ct[x];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
62 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
63 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
64
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
65 /* C[m] = P[m] xor Y[m] */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
66 for (x = 0; x < (int)ptlen; x++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
67 ct[x] = pt[x] ^ Y[x];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
68 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
69
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
70 if (mode == 0) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
71 /* encrypt mode */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
72 /* xor C[m] into checksum */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
73 for (x = 0; x < (int)ptlen; x++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
74 ocb->checksum[x] ^= ct[x];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
75 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
76 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
77
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
78 /* xor Y[m] and Z[m] into checksum */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
79 for (x = 0; x < ocb->block_len; x++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
80 ocb->checksum[x] ^= Y[x] ^ Z[x];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
81 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
82
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
83 /* encrypt checksum, er... tag!! */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
84 cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key);
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
85
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
86 /* now store it */
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
87 for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) {
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
88 tag[x] = X[x];
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
89 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
90 *taglen = x;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
91
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
92 #ifdef CLEAN_STACK
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
93 zeromem(X, sizeof(X));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
94 zeromem(Y, sizeof(Y));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
95 zeromem(Z, sizeof(Z));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
96 zeromem(ocb, sizeof(*ocb));
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
97 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
98 return CRYPT_OK;
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
99 }
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
100
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
101 #endif
7faae8f46238 Branch renaming
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
102