~ubuntu-branches/ubuntu/utopic/dropbear/utopic-proposed

« back to all changes in this revision

Viewing changes to libtomcrypt/ocb_init.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Johnston
  • Date: 2005-12-08 19:20:21 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051208192021-nyp9rwnt77nsg6ty
Tags: 0.47-1
* New upstream release.
* SECURITY: Fix incorrect buffer sizing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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, tomstdenis@iahu.ca, 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
 
   XMEMCPY(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