Revert "Merge branch 'upstream' into tizen"
[platform/upstream/nettle.git] / umac-l2.c
1 /* umac-l2.c
2  */
3
4 /* nettle, low-level cryptographics library
5  *
6  * Copyright (C) 2013 Niels Möller
7  *
8  * The nettle library is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or (at your
11  * option) any later version.
12  *
13  * The nettle library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16  * License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with the nettle library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21  * MA 02111-1301, USA.
22  */
23
24 #if HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include <assert.h>
29 #include <string.h>
30
31 #include "umac.h"
32
33 #include "macros.h"
34
35 /* Same mask applied to low and high halves */
36 #define KEY_MASK 0x01ffffffUL
37
38 #if WORDS_BIGENDIAN
39 #define BE_SWAP32(x) x
40 #else
41 #define BE_SWAP32(x)                            \
42   ((ROTL32(8,  x) & 0x00FF00FFUL) |             \
43    (ROTL32(24, x) & 0xFF00FF00UL))
44 #endif
45
46 void
47 _umac_l2_init (unsigned size, uint32_t *k)
48 {
49   unsigned i;
50   for (i = 0; i < size; i++)
51     {
52       uint32_t w = k[i];
53       w = BE_SWAP32 (w);
54       k[i] = w & KEY_MASK;
55     }
56 }
57
58 void
59 _umac_l2(const uint32_t *key, uint64_t *state, unsigned n,
60          uint64_t count, const uint64_t *m)
61 {
62   uint64_t *prev = state + 2*n;
63   unsigned i;
64
65   if (count == 0)
66     memcpy (prev, m, n * sizeof(*m));
67   else if (count == 1)
68     for (i = 0; i < n; i++, key += 6)
69       {
70         uint64_t y = _umac_poly64 (key[0], key[1], 1, prev[i]);
71         state[2*i+1] = _umac_poly64 (key[0], key[1], y, m[i]);
72       }
73   else if (count < UMAC_POLY64_BLOCKS)
74     for (i = 0; i < n; i++, key += 6)
75       state[2*i+1] = _umac_poly64 (key[0], key[1], state[2*i+1], m[i]);
76   else if (count % 2 == 0)
77     {
78       if (count == UMAC_POLY64_BLOCKS)
79         for (i = 0, key += 2; i < n; i++, key += 6)
80           {
81             uint64_t y = state[2*i+1];
82             if (y >= UMAC_P64)
83               y -= UMAC_P64;
84             state[2*i] = 0;
85             state[2*i+1] = 1;
86
87             _umac_poly128 (key, state + 2*i, 0, y);
88           }
89       memcpy (prev, m, n * sizeof(*m));
90     }
91   else
92     for (i = 0, key += 2; i < n; i++, key += 6)
93       _umac_poly128 (key, state + 2*i, prev[i], m[i]);
94 }
95
96 void
97 _umac_l2_final(const uint32_t *key, uint64_t *state, unsigned n,
98                uint64_t count)
99 {
100   uint64_t *prev = state + 2*n;
101   unsigned i;
102
103   assert (count > 0);
104   if (count == 1)
105     for (i = 0; i < n; i++)
106       {
107         *state++ = 0;
108         *state++ = *prev++;
109       }
110   else if (count <= UMAC_POLY64_BLOCKS)
111     for (i = 0; i < n; i++)
112       {
113         uint64_t y;
114         *state++ = 0;
115
116         y = *state;
117         if (y >= UMAC_P64)
118           y -= UMAC_P64;
119         *state++ = y;
120       }
121   else
122     {
123       uint64_t pad = (uint64_t) 1 << 63;
124       if (count % 2 == 1)
125         for (i = 0, key += 2; i < n; i++, key += 6)
126           _umac_poly128 (key, state + 2*i, prev[i], pad);
127       else
128         for (i = 0, key += 2; i < n; i++, key += 6)
129           _umac_poly128 (key, state + 2*i, pad, 0);
130
131       for (i = 0; i < n; i++, state += 2)
132         {
133           uint64_t yh, yl;
134
135           yh = state[0];
136           yl = state[1];
137           if (yh == UMAC_P128_HI && yl >= UMAC_P128_LO)
138             {
139               state[0] = 0;
140               state[1] = yl -= UMAC_P128_LO;
141             }
142         }
143     }
144 }