|
@@ -15,6 +15,57 @@
|
|
|
|
|
|
#ifdef LTC_OCB3_MODE
|
|
#ifdef LTC_OCB3_MODE
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ Sets 'ocb->Offset_current' to 'Offset_0' value (internal function)
|
|
|
|
+ @param ocb The OCB state
|
|
|
|
+ @param nonce The session nonce
|
|
|
|
+ @param noncelen The length of the session nonce (octets)
|
|
|
|
+*/
|
|
|
|
+static void _ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen, unsigned long taglen)
|
|
|
|
+{
|
|
|
|
+ int x, y, bottom;
|
|
|
|
+ int idx, shift;
|
|
|
|
+ unsigned char iNonce[MAXBLOCKSIZE];
|
|
|
|
+ unsigned char iKtop[MAXBLOCKSIZE];
|
|
|
|
+ unsigned char iStretch[MAXBLOCKSIZE+8];
|
|
|
|
+
|
|
|
|
+ /* Nonce = zeros(127-bitlen(N)) || 1 || N */
|
|
|
|
+ zeromem(iNonce, sizeof(iNonce));
|
|
|
|
+ for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) {
|
|
|
|
+ iNonce[x] = nonce[noncelen-y-1];
|
|
|
|
+ }
|
|
|
|
+ iNonce[x] = 0x01;
|
|
|
|
+ iNonce[0] |= ((taglen*8) % 128) << 1;
|
|
|
|
+
|
|
|
|
+ /* bottom = str2num(Nonce[123..128]) */
|
|
|
|
+ bottom = iNonce[ocb->block_len-1] & 0x3F;
|
|
|
|
+
|
|
|
|
+ /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */
|
|
|
|
+ iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0;
|
|
|
|
+ if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) {
|
|
|
|
+ zeromem(ocb->Offset_current, ocb->block_len);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
|
|
|
|
+ for (x = 0; x < ocb->block_len; x++) {
|
|
|
|
+ iStretch[x] = iKtop[x];
|
|
|
|
+ }
|
|
|
|
+ for (y = 0; y < 8; y++) {
|
|
|
|
+ iStretch[x+y] = iKtop[y] ^ iKtop[y+1];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Offset_0 = Stretch[1+bottom..128+bottom] */
|
|
|
|
+ idx = bottom / 8;
|
|
|
|
+ shift = (bottom % 8);
|
|
|
|
+ for (x = 0; x < ocb->block_len; x++) {
|
|
|
|
+ ocb->Offset_current[x] = iStretch[idx+x] << shift;
|
|
|
|
+ if (shift > 0) {
|
|
|
|
+ ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static const struct {
|
|
static const struct {
|
|
int len;
|
|
int len;
|
|
unsigned char poly_mul[MAXBLOCKSIZE];
|
|
unsigned char poly_mul[MAXBLOCKSIZE];
|
|
@@ -120,7 +171,7 @@ int ocb3_init(ocb3_state *ocb, int cipher,
|
|
}
|
|
}
|
|
|
|
|
|
/* initialize ocb->Offset_current = Offset_0 */
|
|
/* initialize ocb->Offset_current = Offset_0 */
|
|
- ocb3_int_calc_offset_zero(ocb, nonce, noncelen, taglen);
|
|
|
|
|
|
+ _ocb3_int_calc_offset_zero(ocb, nonce, noncelen, taglen);
|
|
|
|
|
|
/* initialize checksum to all zeros */
|
|
/* initialize checksum to all zeros */
|
|
zeromem(ocb->checksum, ocb->block_len);
|
|
zeromem(ocb->checksum, ocb->block_len);
|