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 (at) gmail.com, http://libtomcrypt.com 10 */ 11 12 /** 13 @file ocb_init.c 14 OCB implementation, initialize state, by Tom St Denis 15 */ 16 #include "tomcrypt.h" 17 18 #ifdef OCB_MODE 19 20 static const struct { 21 int len; 22 unsigned char poly_div[MAXBLOCKSIZE], 23 poly_mul[MAXBLOCKSIZE]; 24 } polys[] = { 25 { 26 8, 27 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, 28 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } 29 }, { 30 16, 31 { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, 33 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } 35 } 36 }; 37 38 /** 39 Initialize an OCB context. 40 @param ocb [out] The destination of the OCB state 41 @param cipher The index of the desired cipher 42 @param key The secret key 43 @param keylen The length of the secret key (octets) 44 @param nonce The session nonce (length of the block size of the cipher) 45 @return CRYPT_OK if successful 46 */ 47 int ocb_init(ocb_state *ocb, int cipher, 48 const unsigned char *key, unsigned long keylen, const unsigned char *nonce) 49 { 50 int poly, x, y, m, err; 51 52 LTC_ARGCHK(ocb != NULL); 53 LTC_ARGCHK(key != NULL); 54 LTC_ARGCHK(nonce != NULL); 55 56 /* valid cipher? */ 57 if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { 58 return err; 59 } 60 61 /* determine which polys to use */ 62 ocb->block_len = cipher_descriptor[cipher].block_length; 63 for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { 64 if (polys[poly].len == ocb->block_len) { 65 break; 66 } 67 } 68 if (polys[poly].len != ocb->block_len) { 69 return CRYPT_INVALID_ARG; 70 } 71 72 /* schedule the key */ 73 if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { 74 return err; 75 } 76 77 /* find L = E[0] */ 78 zeromem(ocb->L, ocb->block_len); 79 if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) { 80 return err; 81 } 82 83 /* find R = E[N xor L] */ 84 for (x = 0; x < ocb->block_len; x++) { 85 ocb->R[x] = ocb->L[x] ^ nonce[x]; 86 } 87 if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) { 88 return err; 89 } 90 91 /* find Ls[i] = L << i for i == 0..31 */ 92 XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len); 93 for (x = 1; x < 32; x++) { 94 m = ocb->Ls[x-1][0] >> 7; 95 for (y = 0; y < ocb->block_len-1; y++) { 96 ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255; 97 } 98 ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255; 99 100 if (m == 1) { 101 for (y = 0; y < ocb->block_len; y++) { 102 ocb->Ls[x][y] ^= polys[poly].poly_mul[y]; 103 } 104 } 105 } 106 107 /* find Lr = L / x */ 108 m = ocb->L[ocb->block_len-1] & 1; 109 110 /* shift right */ 111 for (x = ocb->block_len - 1; x > 0; x--) { 112 ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255; 113 } 114 ocb->Lr[0] = ocb->L[0] >> 1; 115 116 if (m == 1) { 117 for (x = 0; x < ocb->block_len; x++) { 118 ocb->Lr[x] ^= polys[poly].poly_div[x]; 119 } 120 } 121 122 /* set Li, checksum */ 123 zeromem(ocb->Li, ocb->block_len); 124 zeromem(ocb->checksum, ocb->block_len); 125 126 /* set other params */ 127 ocb->block_index = 1; 128 ocb->cipher = cipher; 129 130 return CRYPT_OK; 131 } 132 133 #endif 134 135 /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_init.c,v $ */ 136 /* $Revision: 1.5 $ */ 137 /* $Date: 2006/03/31 14:15:35 $ */ 138