• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include "hitls_build.h"
17 #ifdef HITLS_CRYPTO_GCM
18 
19 #include "bsl_sal.h"
20 #include "crypt_utils.h"
21 #include "modes_local.h"
22 
23 /* table[i] = (P^4)*i, P = 0x4000000000000000, i = 0...16 */
24 static const uint64_t TABLE_P4_BITS[16] = {
25     0x0000000000000000, 0x1c20000000000000, 0x3840000000000000, 0x2460000000000000,
26     0x7080000000000000, 0x6ca0000000000000, 0x48c0000000000000, 0x54e0000000000000,
27     0xe100000000000000, 0xfd20000000000000, 0xd940000000000000, 0xc560000000000000,
28     0x9180000000000000, 0x8da0000000000000, 0xa9c0000000000000, 0xb5e0000000000000
29 };
30 
31 // Calculate n*H, n is in 0 .... 16
GcmTableGen4bit(uint8_t key[GCM_BLOCKSIZE],MODES_GCM_GF128 hTable[16])32 void GcmTableGen4bit(uint8_t key[GCM_BLOCKSIZE], MODES_GCM_GF128 hTable[16])
33 {
34     uint32_t i;
35     uint32_t j;
36     const uint64_t r = 0xE100000000000000;
37     hTable[0].h = 0;
38     hTable[0].l = 0;
39     // The intermediate term of the table (16 / 2 = = 8) is H itself.
40     hTable[8].h = Uint64FromBeBytes(key);
41     // The intermediate term of the table (16 / 2 = = 8) is H itself.
42     hTable[8].l = Uint64FromBeBytes(key + sizeof(uint64_t));
43 
44     for (i = 4; i > 0; i >>= 1) { // 4-bit table, the value of the 2^n item is calculated first.
45         // cyclically shift to right by 1bit. The upper 1 bit of h is combined with the lower 63 bits of l.
46         hTable[i].l = (hTable[ i * 2].h << 63) | (hTable[ i * 2].l >> 1);
47         hTable[i].h = (hTable[ i * 2].h >> 1) ^ ((hTable[ i * 2].l & 1) * r); // the value of the 2^n item
48     }
49     for (i = 1; i < 16; i <<= 1) {
50         for (j = 1; j < i; j++) {
51             hTable[i + j].h = hTable[i].h ^ hTable[j].h;
52             hTable[i + j].l = hTable[i].l ^ hTable[j].l;
53         }
54     }
55 }
56 
57 // Calculate t = t * H
GcmHashMultiBlock(uint8_t t[GCM_BLOCKSIZE],const MODES_GCM_GF128 hTable[16],const uint8_t * in,uint32_t inLen)58 void GcmHashMultiBlock(uint8_t t[GCM_BLOCKSIZE], const MODES_GCM_GF128 hTable[16], const uint8_t *in, uint32_t inLen)
59 {
60     MODES_GCM_GF128 x;
61     uint8_t r;
62     uint8_t h, l, tag;   // Ciphertext information, digest information, and non-sensitive information.
63     const uint8_t *tempIn = in;
64     for (uint32_t i = 0; i < inLen; i += GCM_BLOCKSIZE) {
65         uint8_t cnt = GCM_BLOCKSIZE - 1;
66         x.h = 0;
67         x.l = 0;
68         while (1) {
69             tag = t[cnt] ^ tempIn[cnt];
70 
71             l = tag & 0xf;
72             h = (tag >> 4) & 0xf;
73             x.h ^= hTable[l].h;
74             x.l ^= hTable[l].l;
75 
76             r = (x.l & 0xf);
77             // Cyclically shift to right by 4 bits. The upper 4 bits of h is combined with the lower 60 bits of l.
78             x.l  = (x.h << 60) | (x.l >> 4);
79             x.h  = (x.h >> 4); // Cyclically shift to right by 4 bits.
80             x.h ^= TABLE_P4_BITS[r];
81 
82             x.h ^= hTable[h].h;
83             x.l ^= hTable[h].l;
84             if (cnt == 0) {
85                 break;
86             }
87             cnt--;
88             r = (x.l & 0xf);
89             // Cyclically shift to right by 4 bits. The upper 4 bits of h is combined with the lower 60 bits of l.
90             x.l  = (x.h << 60) | (x.l >> 4);
91             x.h  = (x.h >> 4); // Cyclically shift to right by 4 bits.
92             x.h ^= TABLE_P4_BITS[r];
93         }
94         tempIn += GCM_BLOCKSIZE;
95         Uint64ToBeBytes(x.h, t);
96         Uint64ToBeBytes(x.l, t + 8);
97     }
98     // Clear sensitive information.
99     BSL_SAL_CleanseData(&x, sizeof(MODES_GCM_GF128));
100     BSL_SAL_CleanseData(&r, sizeof(uint8_t));
101 }
102 #endif