~zooko/cryptopp/trunk

« back to all changes in this revision

Viewing changes to vmac.cpp

  • Committer: weidai
  • Date: 2009-03-13 11:15:21 UTC
  • Revision ID: svn-v4:57ff6487-cd31-0410-9ec3-f628ee90f5f0:trunk/c5:450
fix compile on OpenSolaris 8.11

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 
9
9
NAMESPACE_BEGIN(CryptoPP)
10
10
 
11
 
#if defined(_MSC_VER) && !defined(CRYPTOPP_SLOW_WORD64)
 
11
#if defined(_MSC_VER) && !CRYPTOPP_BOOL_SLOW_WORD64
12
12
#include <intrin.h>
13
13
#endif
14
14
 
25
25
#undef const
26
26
#endif
27
27
#if VMAC_BOOL_WORD128
 
28
#ifdef __powerpc__
 
29
// workaround GCC Bug 31690: ICE with const __uint128_t and C++ front-end
 
30
#define m126                            ((word128(m62)<<64)|m64)
 
31
#else
28
32
static const word128 m126 = (word128(m62)<<64)|m64;              /* 126-bit mask      */
29
33
#endif
 
34
#endif
30
35
 
31
36
void VMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &params)
32
37
{
52
57
 
53
58
        /* Fill nh key */
54
59
        in[0] = 0x80; 
55
 
        for (i = 0; i < m_nhKeySize()*sizeof(word64); i += blockSize)
56
 
        {
57
 
                cipher.ProcessBlock(in, out.BytePtr());
58
 
                ConditionalByteReverse(BIG_ENDIAN_ORDER, m_nhKey()+i/sizeof(word64), out.begin(), blockSize);
59
 
                in[15]++;
60
 
        }
 
60
        cipher.AdvancedProcessBlocks(in, NULL, (byte *)m_nhKey(), m_nhKeySize()*sizeof(word64), cipher.BT_InBlockIsCounter);
 
61
        ConditionalByteReverse<word64>(BIG_ENDIAN_ORDER, m_nhKey(), m_nhKey(), m_nhKeySize()*sizeof(word64));
61
62
 
62
63
        /* Fill poly key */
63
64
        in[0] = 0xC0;
84
85
                } while ((l3Key[i*2+0] >= p64) || (l3Key[i*2+1] >= p64));
85
86
 
86
87
        m_padCached = false;
87
 
        Resynchronize(GetIVAndThrowIfInvalid(params));
 
88
        size_t nonceLength;
 
89
        const byte *nonce = GetIVAndThrowIfInvalid(params, nonceLength);
 
90
        Resynchronize(nonce, (int)nonceLength);
88
91
}
89
92
 
90
93
void VMAC_Base::GetNextIV(RandomNumberGenerator &rng, byte *IV)
93
96
        IV[0] &= 0x7f;
94
97
}
95
98
 
96
 
void VMAC_Base::Resynchronize(const byte *IV)
 
99
void VMAC_Base::Resynchronize(const byte *nonce, int len)
97
100
{
98
 
        int s = IVSize();
 
101
        size_t length = ThrowIfInvalidIVLength(len);
 
102
        size_t s = IVSize();
 
103
        byte *storedNonce = m_nonce();
 
104
 
99
105
        if (m_is128)
100
106
        {
101
 
                memcpy(m_nonce(), IV, s);
102
 
                AccessCipher().ProcessBlock(m_nonce(), m_pad());
 
107
                memset(storedNonce, 0, s-length);
 
108
                memcpy(storedNonce+s-length, nonce, length);
 
109
                AccessCipher().ProcessBlock(storedNonce, m_pad());
103
110
        }
104
111
        else
105
112
        {
106
 
                m_padCached = m_padCached && (m_nonce()[s-1] | 1) == (IV[s-1] | 1) && memcmp(m_nonce(), IV, s-1) == 0;
 
113
                if (m_padCached && (storedNonce[s-1] | 1) == (nonce[length-1] | 1))
 
114
                {
 
115
                        m_padCached = VerifyBufsEqual(storedNonce+s-length, nonce, length-1);
 
116
                        for (size_t i=0; m_padCached && i<s-length; i++)
 
117
                                m_padCached = (storedNonce[i] == 0);
 
118
                }
107
119
                if (!m_padCached)
108
120
                {
109
 
                        memcpy(m_nonce(), IV, s);
110
 
                        m_nonce()[s-1] &= 0xfe;
111
 
                        AccessCipher().ProcessBlock(m_nonce(), m_pad());
 
121
                        memset(storedNonce, 0, s-length);
 
122
                        memcpy(storedNonce+s-length, nonce, length-1);
 
123
                        storedNonce[s-1] = nonce[length-1] & 0xfe;
 
124
                        AccessCipher().ProcessBlock(storedNonce, m_pad());
112
125
                        m_padCached = true;
113
126
                }
114
 
                m_nonce()[s-1] = IV[s-1];
 
127
                storedNonce[s-1] = nonce[length-1];
115
128
        }
116
129
        m_isFirstBlock = true;
117
130
        Restart();
120
133
void VMAC_Base::HashEndianCorrectedBlock(const word64 *data)
121
134
{
122
135
        assert(false);
 
136
        throw 0;
123
137
}
124
138
 
125
139
#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86
132
146
{
133
147
        const word64 *nhK = m_nhKey();
134
148
        word64 *polyS = m_polyState();
 
149
        word32 L1KeyLength = m_L1KeyLength;
135
150
 
136
151
#ifdef __GNUC__
137
152
        word32 temp;
141
156
        AS2(    mov             %1, %%ebx)
142
157
        ".intel_syntax noprefix;"
143
158
#else
144
 
        #if _MSC_VER < 1300
145
 
        word32 L1KeyLength = m_L1KeyLength;
 
159
        #if _MSC_VER < 1300 || defined(__INTEL_COMPILER)
146
160
        char isFirstBlock = m_isFirstBlock;
147
161
        AS2(    mov             ebx, [L1KeyLength])
148
162
        AS2(    mov             dl, [isFirstBlock])
362
376
        ".att_syntax prefix;"
363
377
        AS2(    mov     %0, %%ebx)
364
378
                : "=m" (temp)
365
 
                : "m" (m_L1KeyLength), "c" (blocksRemainingInWord64), "S" (data), "D" (nhK+tagPart*2), "d" (m_isFirstBlock), "a" (polyS+tagPart*4)
 
379
                : "m" (L1KeyLength), "c" (blocksRemainingInWord64), "S" (data), "D" (nhK+tagPart*2), "d" (m_isFirstBlock), "a" (polyS+tagPart*4)
366
380
                : "memory", "cc"
367
381
        );
368
382
#endif
385
399
                #define MUL64(rh,rl,i1,i2)              asm ("mulq %3" : "=a"(rl), "=d"(rh) : "a"(i1), "g"(i2) : "cc");
386
400
                #define AccumulateNH(a, b, c)   asm ("mulq %3; addq %%rax, %0; adcq %%rdx, %1" : "+r"(a##0), "+r"(a##1) : "a"(b), "g"(c) : "%rdx", "cc");
387
401
                #define ADD128(rh,rl,ih,il)     asm ("addq %3, %1; adcq %2, %0" : "+r"(rh),"+r"(rl) : "r"(ih),"r"(il) : "cc");
388
 
        #elif defined(_MSC_VER) && !defined(CRYPTOPP_SLOW_WORD64)
 
402
        #elif defined(_MSC_VER) && !CRYPTOPP_BOOL_SLOW_WORD64
389
403
                #define DeclareNH(a) word64 a##0=0, a##1=0
390
404
                #define MUL64(rh,rl,i1,i2)   (rl) = _umul128(i1,i2,&(rh));
391
405
                #define AccumulateNH(a, b, c)   {\
472
486
                DeclareNH(nhA);
473
487
                DeclareNH(nhB);
474
488
 
 
489
                i = 0;
475
490
                if (blocksRemainingInWord64 < L1KeyLengthInWord64)
476
491
                {
477
492
                        if (blocksRemainingInWord64 % 8)
478
493
                        {
479
494
                                innerLoopEnd = blocksRemainingInWord64 % 8;
480
 
                                for (i=0; i<innerLoopEnd; i+=2)
 
495
                                for (; i<innerLoopEnd; i+=2)
481
496
                                        INNER_LOOP_ITERATION(0);
482
 
                                blocksRemainingInWord64 -= innerLoopEnd;
483
 
                                data += innerLoopEnd;
484
497
                        }
485
498
                        innerLoopEnd = blocksRemainingInWord64;
486
499
                }
487
 
 
488
 
                for (i=0; i<innerLoopEnd; i+=8)
 
500
                for (; i<innerLoopEnd; i+=8)
489
501
                {
490
502
                        INNER_LOOP_ITERATION(0);
491
503
                        INNER_LOOP_ITERATION(1);