DLMS-SPODES-client 0.19.35__py3-none-any.whl → 0.19.37__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- DLMS_SPODES_client/FCS16.py +39 -39
- DLMS_SPODES_client/__init__.py +12 -12
- DLMS_SPODES_client/client.py +2093 -2093
- DLMS_SPODES_client/gurux_common/enums/TraceLevel.py +21 -21
- DLMS_SPODES_client/gurux_dlms/AesGcmParameter.py +37 -37
- DLMS_SPODES_client/gurux_dlms/CountType.py +16 -16
- DLMS_SPODES_client/gurux_dlms/GXByteBuffer.py +545 -545
- DLMS_SPODES_client/gurux_dlms/GXCiphering.py +196 -196
- DLMS_SPODES_client/gurux_dlms/GXDLMS.py +426 -426
- DLMS_SPODES_client/gurux_dlms/GXDLMSChippering.py +237 -237
- DLMS_SPODES_client/gurux_dlms/GXDLMSChipperingStream.py +977 -977
- DLMS_SPODES_client/gurux_dlms/GXDLMSConfirmedServiceError.py +90 -90
- DLMS_SPODES_client/gurux_dlms/GXDLMSException.py +139 -139
- DLMS_SPODES_client/gurux_dlms/GXDLMSLNParameters.py +33 -33
- DLMS_SPODES_client/gurux_dlms/GXDLMSSNParameters.py +21 -21
- DLMS_SPODES_client/gurux_dlms/GXDLMSSettings.py +254 -254
- DLMS_SPODES_client/gurux_dlms/GXReplyData.py +87 -87
- DLMS_SPODES_client/gurux_dlms/HdlcControlFrame.py +9 -9
- DLMS_SPODES_client/gurux_dlms/MBusCommand.py +8 -8
- DLMS_SPODES_client/gurux_dlms/MBusEncryptionMode.py +27 -27
- DLMS_SPODES_client/gurux_dlms/ResponseType.py +8 -8
- DLMS_SPODES_client/gurux_dlms/SetResponseType.py +29 -29
- DLMS_SPODES_client/gurux_dlms/_HDLCInfo.py +9 -9
- DLMS_SPODES_client/gurux_dlms/__init__.py +75 -75
- DLMS_SPODES_client/gurux_dlms/enums/Access.py +12 -12
- DLMS_SPODES_client/gurux_dlms/enums/ApplicationReference.py +14 -14
- DLMS_SPODES_client/gurux_dlms/enums/Authentication.py +41 -41
- DLMS_SPODES_client/gurux_dlms/enums/BerType.py +35 -35
- DLMS_SPODES_client/gurux_dlms/enums/Command.py +285 -285
- DLMS_SPODES_client/gurux_dlms/enums/Definition.py +9 -9
- DLMS_SPODES_client/gurux_dlms/enums/ErrorCode.py +46 -46
- DLMS_SPODES_client/gurux_dlms/enums/ExceptionServiceError.py +12 -12
- DLMS_SPODES_client/gurux_dlms/enums/HardwareResource.py +10 -10
- DLMS_SPODES_client/gurux_dlms/enums/HdlcFrameType.py +9 -9
- DLMS_SPODES_client/gurux_dlms/enums/Initiate.py +10 -10
- DLMS_SPODES_client/gurux_dlms/enums/LoadDataSet.py +13 -13
- DLMS_SPODES_client/gurux_dlms/enums/ObjectType.py +306 -306
- DLMS_SPODES_client/gurux_dlms/enums/Priority.py +7 -7
- DLMS_SPODES_client/gurux_dlms/enums/RequestTypes.py +9 -9
- DLMS_SPODES_client/gurux_dlms/enums/Security.py +14 -14
- DLMS_SPODES_client/gurux_dlms/enums/Service.py +16 -16
- DLMS_SPODES_client/gurux_dlms/enums/ServiceClass.py +9 -9
- DLMS_SPODES_client/gurux_dlms/enums/ServiceError.py +8 -8
- DLMS_SPODES_client/gurux_dlms/enums/Standard.py +18 -18
- DLMS_SPODES_client/gurux_dlms/enums/StateError.py +7 -7
- DLMS_SPODES_client/gurux_dlms/enums/Task.py +10 -10
- DLMS_SPODES_client/gurux_dlms/enums/VdeStateError.py +10 -10
- DLMS_SPODES_client/gurux_dlms/enums/__init__.py +33 -33
- DLMS_SPODES_client/gurux_dlms/internal/_GXCommon.py +1673 -1673
- DLMS_SPODES_client/logger.py +56 -56
- DLMS_SPODES_client/services.py +90 -90
- DLMS_SPODES_client/session.py +363 -363
- DLMS_SPODES_client/settings.py +48 -48
- DLMS_SPODES_client/task.py +1884 -1884
- {dlms_spodes_client-0.19.35.dist-info → dlms_spodes_client-0.19.37.dist-info}/METADATA +29 -29
- dlms_spodes_client-0.19.37.dist-info/RECORD +61 -0
- {dlms_spodes_client-0.19.35.dist-info → dlms_spodes_client-0.19.37.dist-info}/WHEEL +1 -1
- dlms_spodes_client-0.19.35.dist-info/RECORD +0 -61
- {dlms_spodes_client-0.19.35.dist-info → dlms_spodes_client-0.19.37.dist-info}/entry_points.txt +0 -0
- {dlms_spodes_client-0.19.35.dist-info → dlms_spodes_client-0.19.37.dist-info}/top_level.txt +0 -0
|
@@ -1,977 +1,977 @@
|
|
|
1
|
-
from __future__ import print_function
|
|
2
|
-
from .GXByteBuffer import GXByteBuffer
|
|
3
|
-
from .enums.Security import Security
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class GXDLMSChipperingStream:
|
|
7
|
-
"""
|
|
8
|
-
Implements GMAC. This class is based to this doc:
|
|
9
|
-
http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
# Consts.
|
|
13
|
-
BLOCK_SIZE = 16
|
|
14
|
-
TAG_SIZE = 0x10
|
|
15
|
-
IV = [0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6]
|
|
16
|
-
|
|
17
|
-
#schedule Vector (powers of x).
|
|
18
|
-
R_CON = (0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,\
|
|
19
|
-
0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,\
|
|
20
|
-
0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,\
|
|
21
|
-
0xc5, 0x91)
|
|
22
|
-
|
|
23
|
-
#S box
|
|
24
|
-
@classmethod
|
|
25
|
-
def aes1Encrypt(cls, data: bytearray, offset: int, secret: bytearray):
|
|
26
|
-
round_ = 0
|
|
27
|
-
i = 0
|
|
28
|
-
key = secret.copy()
|
|
29
|
-
while round_ < 10:
|
|
30
|
-
i = 0
|
|
31
|
-
while i < 16:
|
|
32
|
-
data[i + offset] = cls.S_BOX[(data[i + offset] ^ key[i]) & 0xFF]
|
|
33
|
-
i += 1
|
|
34
|
-
buf1 = data[1 + offset]
|
|
35
|
-
data[1 + offset] = data[5 + offset]
|
|
36
|
-
data[5 + offset] = data[9 + offset]
|
|
37
|
-
data[9 + offset] = data[13 + offset]
|
|
38
|
-
data[13 + offset] = buf1
|
|
39
|
-
buf1 = data[2 + offset]
|
|
40
|
-
buf2 = data[6 + offset]
|
|
41
|
-
data[2 + offset] = data[10 + offset]
|
|
42
|
-
data[6 + offset] = data[14 + offset]
|
|
43
|
-
data[10 + offset] = buf1
|
|
44
|
-
data[14 + offset] = buf2
|
|
45
|
-
buf1 = data[15 + offset]
|
|
46
|
-
data[15 + offset] = data[11 + offset]
|
|
47
|
-
data[11 + offset] = data[7 + offset]
|
|
48
|
-
data[7 + offset] = data[3 + offset]
|
|
49
|
-
data[3 + offset] = buf1
|
|
50
|
-
if round_ < 9:
|
|
51
|
-
i = 0
|
|
52
|
-
while i < 4:
|
|
53
|
-
buf4 = (i << 2) & 0xFF
|
|
54
|
-
buf1 = (data[buf4 + offset] ^ data[buf4 + 1 + offset] ^ data[buf4 + 2 + offset] ^ data[buf4 + 3 + offset]) & 0xFF
|
|
55
|
-
buf2 = data[buf4 + offset] & 0xFF
|
|
56
|
-
buf3 = (data[buf4 + offset] ^ data[buf4 + 1 + offset]) & 0xFF
|
|
57
|
-
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
58
|
-
data[buf4 + offset] = (data[buf4 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
59
|
-
buf3 = (data[buf4 + 1 + offset] ^ data[buf4 + 2 + offset]) & 0xFF
|
|
60
|
-
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
61
|
-
data[buf4 + 1 + offset] = (data[buf4 + 1 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
62
|
-
buf3 = (data[buf4 + 2 + offset] ^ data[buf4 + 3 + offset]) & 0xFF
|
|
63
|
-
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
64
|
-
data[buf4 + 2 + offset] = (data[buf4 + 2 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
65
|
-
buf3 = (data[buf4 + 3 + offset] ^ buf2) & 0xFF
|
|
66
|
-
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
67
|
-
data[buf4 + 3 + offset] = (data[buf4 + 3 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
68
|
-
i += 1
|
|
69
|
-
key[0] = (cls.S_BOX[key[13] & 0xFF] ^ key[0] ^ cls.R_CON[round_]) & 0xFF
|
|
70
|
-
key[1] = (cls.S_BOX[key[14] & 0xFF] ^ key[1]) & 0xFF
|
|
71
|
-
key[2] = (cls.S_BOX[key[15] & 0xFF] ^ key[2]) & 0xFF
|
|
72
|
-
key[3] = (cls.S_BOX[key[12] & 0xFF] ^ key[3]) & 0xFF
|
|
73
|
-
i = 4
|
|
74
|
-
while i < 16:
|
|
75
|
-
key[i] = (key[i] ^ key[i - 4]) & 0xFF
|
|
76
|
-
i += 1
|
|
77
|
-
round_ += 1
|
|
78
|
-
i = 0
|
|
79
|
-
while i < 16:
|
|
80
|
-
data[i + offset] = (data[i + offset] ^ key[i])
|
|
81
|
-
i += 1
|
|
82
|
-
|
|
83
|
-
S_BOX = (0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,\
|
|
84
|
-
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82,\
|
|
85
|
-
0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF,\
|
|
86
|
-
0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F,\
|
|
87
|
-
0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,\
|
|
88
|
-
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12,\
|
|
89
|
-
0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A,\
|
|
90
|
-
0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3,\
|
|
91
|
-
0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,\
|
|
92
|
-
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF,\
|
|
93
|
-
0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,\
|
|
94
|
-
0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D,\
|
|
95
|
-
0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,\
|
|
96
|
-
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7,\
|
|
97
|
-
0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC,\
|
|
98
|
-
0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E,\
|
|
99
|
-
0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,\
|
|
100
|
-
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8,\
|
|
101
|
-
0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA,\
|
|
102
|
-
0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6,\
|
|
103
|
-
0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,\
|
|
104
|
-
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35,\
|
|
105
|
-
0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,\
|
|
106
|
-
0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55,\
|
|
107
|
-
0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,\
|
|
108
|
-
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16)
|
|
109
|
-
|
|
110
|
-
#Inverse sbox
|
|
111
|
-
S_BOX_REVERSED = (0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5,\
|
|
112
|
-
0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c,\
|
|
113
|
-
0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43,\
|
|
114
|
-
0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6,\
|
|
115
|
-
0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3,\
|
|
116
|
-
0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76,\
|
|
117
|
-
0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6,\
|
|
118
|
-
0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d,\
|
|
119
|
-
0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9,\
|
|
120
|
-
0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90,\
|
|
121
|
-
0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58,\
|
|
122
|
-
0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca,\
|
|
123
|
-
0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a,\
|
|
124
|
-
0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97,\
|
|
125
|
-
0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74,\
|
|
126
|
-
0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c,\
|
|
127
|
-
0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5,\
|
|
128
|
-
0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc,\
|
|
129
|
-
0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0,\
|
|
130
|
-
0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88,\
|
|
131
|
-
0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec,\
|
|
132
|
-
0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d,\
|
|
133
|
-
0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b,\
|
|
134
|
-
0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83,\
|
|
135
|
-
0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6,\
|
|
136
|
-
0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d)
|
|
137
|
-
|
|
138
|
-
#Rijndael (AES) Encryption fast table.
|
|
139
|
-
AES = (0xa56363c6, 0x847c7cf8, 0x997777ee,\
|
|
140
|
-
0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,\
|
|
141
|
-
0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7,\
|
|
142
|
-
0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f,\
|
|
143
|
-
0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e,\
|
|
144
|
-
0x0bf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,\
|
|
145
|
-
0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775,\
|
|
146
|
-
0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e,\
|
|
147
|
-
0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, 0x34e5e5d1,\
|
|
148
|
-
0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,\
|
|
149
|
-
0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830,\
|
|
150
|
-
0xa1969637, 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224,\
|
|
151
|
-
0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f,\
|
|
152
|
-
0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,\
|
|
153
|
-
0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4,\
|
|
154
|
-
0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd,\
|
|
155
|
-
0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000,\
|
|
156
|
-
0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,\
|
|
157
|
-
0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94,\
|
|
158
|
-
0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5,\
|
|
159
|
-
0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366,\
|
|
160
|
-
0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,\
|
|
161
|
-
0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2,\
|
|
162
|
-
0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21,\
|
|
163
|
-
0x48383870, 0x04f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf,\
|
|
164
|
-
0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,\
|
|
165
|
-
0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe,\
|
|
166
|
-
0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755,\
|
|
167
|
-
0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932,\
|
|
168
|
-
0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,\
|
|
169
|
-
0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 0xca46468c,\
|
|
170
|
-
0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc,\
|
|
171
|
-
0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74,\
|
|
172
|
-
0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,\
|
|
173
|
-
0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139,\
|
|
174
|
-
0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b,\
|
|
175
|
-
0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c,\
|
|
176
|
-
0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,\
|
|
177
|
-
0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f,\
|
|
178
|
-
0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657,\
|
|
179
|
-
0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8,\
|
|
180
|
-
0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,\
|
|
181
|
-
0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890,\
|
|
182
|
-
0x05030306, 0x01f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a,\
|
|
183
|
-
0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a,\
|
|
184
|
-
0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,\
|
|
185
|
-
0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d,\
|
|
186
|
-
0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa,\
|
|
187
|
-
0x78282850, 0x7adfdfa5, 0x8f8c8c03, 0xf8a1a159, 0x80898909,\
|
|
188
|
-
0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,\
|
|
189
|
-
0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b,\
|
|
190
|
-
0xfc5454a8, 0xd6bbbb6d, 0x3a16162c)
|
|
191
|
-
|
|
192
|
-
AES1_REVERSED = (0x50a7f451, 0x5365417e,\
|
|
193
|
-
0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac,\
|
|
194
|
-
0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5,\
|
|
195
|
-
0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de,\
|
|
196
|
-
0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81,\
|
|
197
|
-
0xa397468d, 0xc6f9d36b, 0xe75f8f03, 0x959c9215, 0xeb7a6dbf,\
|
|
198
|
-
0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,\
|
|
199
|
-
0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be,\
|
|
200
|
-
0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5,\
|
|
201
|
-
0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe,\
|
|
202
|
-
0x942b08f9, 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52,\
|
|
203
|
-
0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x0728ebb2,\
|
|
204
|
-
0x03c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23,\
|
|
205
|
-
0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3,\
|
|
206
|
-
0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,\
|
|
207
|
-
0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b,\
|
|
208
|
-
0xaaef6040, 0x069f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96,\
|
|
209
|
-
0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604,\
|
|
210
|
-
0xff155060, 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967,\
|
|
211
|
-
0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 0x470a7ca1,\
|
|
212
|
-
0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32,\
|
|
213
|
-
0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d,\
|
|
214
|
-
0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,\
|
|
215
|
-
0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080,\
|
|
216
|
-
0xa220dc61, 0x694b775a, 0x161a121c, 0x0aba93e2, 0xe52aa0c0,\
|
|
217
|
-
0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d,\
|
|
218
|
-
0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3,\
|
|
219
|
-
0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b,\
|
|
220
|
-
0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342,\
|
|
221
|
-
0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae,\
|
|
222
|
-
0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,\
|
|
223
|
-
0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8,\
|
|
224
|
-
0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9,\
|
|
225
|
-
0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da,\
|
|
226
|
-
0xa4bfad3f, 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54,\
|
|
227
|
-
0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f,\
|
|
228
|
-
0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810,\
|
|
229
|
-
0x6e639ce8, 0x7bbb3bdb, 0x097826cd, 0xf418596e, 0x01b79aec,\
|
|
230
|
-
0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,\
|
|
231
|
-
0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431,\
|
|
232
|
-
0x31233f2a, 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc,\
|
|
233
|
-
0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0x0e50cd7f,\
|
|
234
|
-
0x2ff69117, 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4,\
|
|
235
|
-
0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x04ea5e9d,\
|
|
236
|
-
0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92,\
|
|
237
|
-
0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859,\
|
|
238
|
-
0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,\
|
|
239
|
-
0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753,\
|
|
240
|
-
0x5baafd5f, 0x146f3ddf, 0x86db4478, 0x81f3afca, 0x3ec468b9,\
|
|
241
|
-
0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28,\
|
|
242
|
-
0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664,\
|
|
243
|
-
0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0)
|
|
244
|
-
|
|
245
|
-
blockSize = 16
|
|
246
|
-
|
|
247
|
-
#
|
|
248
|
-
# * Constructor.
|
|
249
|
-
# *
|
|
250
|
-
# * @param forSecurity
|
|
251
|
-
# * Used security level.
|
|
252
|
-
# * @param forEncrypt
|
|
253
|
-
# * @param blockCipherKey
|
|
254
|
-
# * @param forAad
|
|
255
|
-
# * @param iv
|
|
256
|
-
# * @param forTag
|
|
257
|
-
#
|
|
258
|
-
def __init__(self, forSecurity, forEncrypt, blockCipherKey, forAad, iv, forTag):
|
|
259
|
-
self.security = forSecurity
|
|
260
|
-
self.tag = forTag
|
|
261
|
-
if not self.tag:
|
|
262
|
-
# Tag size is 12 bytes.
|
|
263
|
-
self.tag = bytearray(12)
|
|
264
|
-
elif len(self.tag) != 12:
|
|
265
|
-
raise ValueError("Invalid tag.")
|
|
266
|
-
self.encrypt = forEncrypt
|
|
267
|
-
self.workingKey = self.generateKey(forEncrypt, blockCipherKey)
|
|
268
|
-
if self.encrypt:
|
|
269
|
-
bufLength = GXDLMSChipperingStream.BLOCK_SIZE
|
|
270
|
-
else:
|
|
271
|
-
bufLength = (GXDLMSChipperingStream.BLOCK_SIZE + GXDLMSChipperingStream.TAG_SIZE)
|
|
272
|
-
self.bufBlock = bytearray(bufLength)
|
|
273
|
-
self.aad = forAad
|
|
274
|
-
self.h = bytearray(GXDLMSChipperingStream.BLOCK_SIZE)
|
|
275
|
-
if iv:
|
|
276
|
-
self.processBlock(self.h, 0, self.h, 0)
|
|
277
|
-
self.mArray = [[None] * 32] * 32
|
|
278
|
-
self.init(self.h)
|
|
279
|
-
self.j0 = bytearray(16)
|
|
280
|
-
self.j0[0:len(iv)] = iv[0:]
|
|
281
|
-
self.j0[15] = 0x01
|
|
282
|
-
if self.aad:
|
|
283
|
-
self.s = self.getGHash(self.aad)
|
|
284
|
-
if iv:
|
|
285
|
-
self.counter = self.clone(self.j0)
|
|
286
|
-
self.bytesRemaining = 0
|
|
287
|
-
self.totalLength = 0
|
|
288
|
-
self.output = GXByteBuffer()
|
|
289
|
-
self.c0 = self.c1 = self.c2 = self.c3 = 0
|
|
290
|
-
self.blockSize = 16
|
|
291
|
-
|
|
292
|
-
@classmethod
|
|
293
|
-
def clone(cls, value):
|
|
294
|
-
""" Clone byte array. """
|
|
295
|
-
tmp = value[0:]
|
|
296
|
-
return tmp
|
|
297
|
-
|
|
298
|
-
#
|
|
299
|
-
# * Convert byte array to Little Endian.
|
|
300
|
-
# *
|
|
301
|
-
# * @param data
|
|
302
|
-
# * @param offset
|
|
303
|
-
# * @return
|
|
304
|
-
#
|
|
305
|
-
@classmethod
|
|
306
|
-
def toUInt32(cls, value, offset):
|
|
307
|
-
tmp = value[offset] & 0xFF
|
|
308
|
-
tmp |= (value[offset + 1] << 8) & 0xFF00
|
|
309
|
-
tmp |= (value[offset + 2] << 16) & 0xFF0000
|
|
310
|
-
tmp |= (value[offset + 3] << 24) & 0xFF000000
|
|
311
|
-
return tmp
|
|
312
|
-
|
|
313
|
-
@classmethod
|
|
314
|
-
def subWord(cls, value):
|
|
315
|
-
tmp = cls.S_BOX[value & 0xFF] & 0xFF
|
|
316
|
-
tmp |= (((cls.S_BOX[(value >> 8) & 0xFF]) & 0xFF) << 8) & 0xFF00
|
|
317
|
-
tmp |= (((cls.S_BOX[(value >> 16) & 0xFF]) & 0xFF) << 16) & 0xFF0000
|
|
318
|
-
tmp |= (((cls.S_BOX[(value >> 24) & 0xFF]) & 0xFF) << 24) & 0xFF000000
|
|
319
|
-
return tmp
|
|
320
|
-
|
|
321
|
-
@classmethod
|
|
322
|
-
def shift(cls, value, shift):
|
|
323
|
-
"""
|
|
324
|
-
Shift value.
|
|
325
|
-
"""
|
|
326
|
-
return (value >> shift) | (value << (32 - shift)) & 0xFFFFFFFF
|
|
327
|
-
|
|
328
|
-
#
|
|
329
|
-
# * Initialise the key schedule from the user supplied key.
|
|
330
|
-
# *
|
|
331
|
-
# * @return
|
|
332
|
-
#
|
|
333
|
-
@classmethod
|
|
334
|
-
def starX(cls, value):
|
|
335
|
-
m1 = 0x80808080
|
|
336
|
-
m2 = 0x7f7f7f7f
|
|
337
|
-
m3 = 0x0000001b
|
|
338
|
-
return ((value & m2) << 1) ^ (((value & m1) >> 7) * m3)
|
|
339
|
-
|
|
340
|
-
def imixCol(self, x):
|
|
341
|
-
f2 = self.starX(x)
|
|
342
|
-
f4 = self.starX(f2)
|
|
343
|
-
f8 = self.starX(f4)
|
|
344
|
-
f9 = x ^ f8
|
|
345
|
-
return f2 ^ f4 ^ f8 ^ self.shift(f2 ^ f9, 8) ^ self.shift(f4 ^ f9, 16) ^ self.shift(f9, 24)
|
|
346
|
-
|
|
347
|
-
#
|
|
348
|
-
# * Get bytes from UIn32.
|
|
349
|
-
# *
|
|
350
|
-
# * @param value
|
|
351
|
-
# * @param data
|
|
352
|
-
# * @param offset
|
|
353
|
-
#
|
|
354
|
-
@classmethod
|
|
355
|
-
def getUInt32(cls, value, data, offset):
|
|
356
|
-
data[offset] = value & 0xFF
|
|
357
|
-
data[offset + 1] = (value >> 8) & 0xFF
|
|
358
|
-
data[offset + 2] = (value >> 16) & 0xFF
|
|
359
|
-
data[offset + 3] = (value >> 24) & 0xFF
|
|
360
|
-
|
|
361
|
-
def unPackBlock(self, bytes_, offset):
|
|
362
|
-
self.c0 = self.toUInt32(bytes_, offset)
|
|
363
|
-
self.c1 = self.toUInt32(bytes_, offset + 4)
|
|
364
|
-
self.c2 = self.toUInt32(bytes_, offset + 8)
|
|
365
|
-
self.c3 = self.toUInt32(bytes_, offset + 12)
|
|
366
|
-
|
|
367
|
-
def packBlock(self, bytes_, offset):
|
|
368
|
-
self.getUInt32(self.c0, bytes_, offset)
|
|
369
|
-
self.getUInt32(self.c1, bytes_, offset + 4)
|
|
370
|
-
self.getUInt32(self.c2, bytes_, offset + 8)
|
|
371
|
-
self.getUInt32(self.c3, bytes_, offset + 12)
|
|
372
|
-
|
|
373
|
-
#
|
|
374
|
-
# * Encrypt data block.
|
|
375
|
-
# *
|
|
376
|
-
# * @param key
|
|
377
|
-
#
|
|
378
|
-
def encryptBlock(self, key):
|
|
379
|
-
r = 1
|
|
380
|
-
self.c0 ^= key[0][0]
|
|
381
|
-
self.c1 ^= key[0][1]
|
|
382
|
-
self.c2 ^= key[0][2]
|
|
383
|
-
self.c3 ^= key[0][3]
|
|
384
|
-
while r < self.rounds - 1:
|
|
385
|
-
r0 = (self.AES[self.c0 & 0xFF] & 0xFFFFFFFF)
|
|
386
|
-
r0 ^= (self.shift(self.AES[(self.c1 >> 8) & 0xFF], 24) & 0xFFFFFFFF)
|
|
387
|
-
r0 ^= (self.shift(self.AES[(self.c2 >> 16) & 0xFF], 16) & 0xFFFFFFFF)
|
|
388
|
-
r0 ^= (self.shift(self.AES[(self.c3 >> 24) & 0xFF], 8) & 0xFFFFFFFF)
|
|
389
|
-
r0 ^= (key[r][0] & 0xFFFFFFFF)
|
|
390
|
-
r1 = (self.AES[self.c1 & 0xFF] & 0xFFFFFFFF)
|
|
391
|
-
r1 ^= self.shift(self.AES[(self.c2 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
392
|
-
r1 ^= self.shift(self.AES[(self.c3 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
393
|
-
r1 ^= self.shift(self.AES[(self.c0 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
394
|
-
r1 ^= key[r][1] & 0xFFFFFFFF
|
|
395
|
-
r2 = self.AES[self.c2 & 0xFF] & 0xFFFFFFFF
|
|
396
|
-
r2 ^= self.shift(self.AES[(self.c3 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
397
|
-
r2 ^= self.shift(self.AES[(self.c0 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
398
|
-
r2 ^= self.shift(self.AES[(self.c1 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
399
|
-
r2 ^= key[r][2] & 0xFFFFFFFF
|
|
400
|
-
r3 = self.AES[self.c3 & 0xFF] & 0xFFFFFFFF
|
|
401
|
-
r3 ^= self.shift(self.AES[(self.c0 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
402
|
-
r3 ^= self.shift(self.AES[(self.c1 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
403
|
-
r3 ^= self.shift(self.AES[(self.c2 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
404
|
-
r3 ^= key[r][3] & 0xFFFFFFFF
|
|
405
|
-
r = r + 1
|
|
406
|
-
self.c0 = self.AES[r0 & 0xFF] & 0xFFFFFFFF
|
|
407
|
-
self.c0 ^= self.shift(self.AES[(r1 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
408
|
-
self.c0 ^= self.shift(self.AES[(r2 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
409
|
-
self.c0 ^= self.shift(self.AES[(r3 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
410
|
-
self.c0 ^= key[r][0] & 0xFFFFFFFF
|
|
411
|
-
self.c1 = self.AES[r1 & 0xFF] & 0xFFFFFFFF
|
|
412
|
-
self.c1 ^= self.shift(self.AES[(r2 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
413
|
-
self.c1 ^= self.shift(self.AES[(r3 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
414
|
-
self.c1 ^= self.shift(self.AES[(r0 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
415
|
-
self.c1 ^= key[r][1] & 0xFFFFFFFF
|
|
416
|
-
self.c2 = self.AES[r2 & 0xFF] & 0xFFFFFFFF
|
|
417
|
-
self.c2 ^= self.shift(self.AES[(r3 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
418
|
-
self.c2 ^= self.shift(self.AES[(r0 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
419
|
-
self.c2 ^= self.shift(self.AES[(r1 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
420
|
-
self.c2 ^= key[r][2] & 0xFFFFFFFF
|
|
421
|
-
self.c3 = self.AES[r3 & 0xFF] & 0xFFFFFFFF
|
|
422
|
-
self.c3 ^= self.shift(self.AES[(r0 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
423
|
-
self.c3 ^= self.shift(self.AES[(r1 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
424
|
-
self.c3 ^= self.shift(self.AES[(r2 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
425
|
-
self.c3 ^= key[r][3] & 0xFFFFFFFF
|
|
426
|
-
r = r + 1
|
|
427
|
-
|
|
428
|
-
r0 = self.AES[self.c0 & 0xFF] & 0xFFFFFFFF
|
|
429
|
-
r0 ^= self.shift(self.AES[(self.c1 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
430
|
-
r0 ^= self.shift(self.AES[(self.c2 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
431
|
-
r0 ^= self.shift(self.AES[self.c3 >> 24], 8) & 0xFFFFFFFF
|
|
432
|
-
r0 ^= key[r][0] & 0xFFFFFFFF
|
|
433
|
-
r1 = self.AES[self.c1 & 0xFF] & 0xFFFFFFFF
|
|
434
|
-
r1 ^= self.shift(self.AES[(self.c2 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
435
|
-
r1 ^= self.shift(self.AES[(self.c3 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
436
|
-
r1 ^= self.shift(self.AES[self.c0 >> 24], 8) & 0xFFFFFFFF
|
|
437
|
-
r1 ^= key[r][1] & 0xFFFFFFFF
|
|
438
|
-
r2 = self.AES[self.c2 & 0xFF] & 0xFFFFFFFF
|
|
439
|
-
r2 ^= self.shift(self.AES[(self.c3 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
440
|
-
r2 ^= self.shift(self.AES[(self.c0 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
441
|
-
r2 ^= self.shift(self.AES[self.c1 >> 24], 8) & 0xFFFFFFFF
|
|
442
|
-
r2 ^= key[r][2] & 0xFFFFFFFF
|
|
443
|
-
r3 = self.AES[self.c3 & 0xFF] & 0xFFFFFFFF
|
|
444
|
-
r3 ^= self.shift(self.AES[(self.c0 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
445
|
-
r3 ^= self.shift(self.AES[(self.c1 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
446
|
-
r3 ^= self.shift(self.AES[self.c2 >> 24], 8) & 0xFFFFFFFF
|
|
447
|
-
r3 ^= key[r][3] & 0xFFFFFFFF
|
|
448
|
-
r += 1
|
|
449
|
-
self.c0 = (self.S_BOX[r0 & 0xFF] & 0xFF) & 0xFFFFFFFF
|
|
450
|
-
self.c0 ^= ((self.S_BOX[(r1 >> 8) & 0xFF] & 0xFF) << 8) & 0xFFFFFFFF
|
|
451
|
-
self.c0 ^= ((self.S_BOX[(r2 >> 16) & 0xFF] & 0xFF) << 16) & 0xFFFFFFFF
|
|
452
|
-
self.c0 ^= ((self.S_BOX[r3 >> 24] & 0xFF) << 24) & 0xFFFFFFFF
|
|
453
|
-
self.c0 ^= key[r][0] & 0xFFFFFFFF
|
|
454
|
-
self.c1 = (self.S_BOX[r1 & 0xFF] & 0xFF) & 0xFFFFFFFF
|
|
455
|
-
self.c1 ^= ((self.S_BOX[(r2 >> 8) & 0xFF] & 0xFF) << 8) & 0xFFFFFFFF
|
|
456
|
-
self.c1 ^= ((self.S_BOX[(r3 >> 16) & 0xFF] & 0xFF) << 16) & 0xFFFFFFFF
|
|
457
|
-
self.c1 ^= ((self.S_BOX[r0 >> 24] & 0xFF) << 24) & 0xFFFFFFFF
|
|
458
|
-
self.c1 ^= key[r][1] & 0xFFFFFFFF
|
|
459
|
-
self.c2 = (self.S_BOX[r2 & 0xFF] & 0xFF) & 0xFFFFFFFF
|
|
460
|
-
self.c2 ^= ((self.S_BOX[(r3 >> 8) & 0xFF] & 0xFF) << 8) & 0xFFFFFFFF
|
|
461
|
-
self.c2 ^= ((self.S_BOX[(r0 >> 16) & 0xFF] & 0xFF) << 16) & 0xFFFFFFFF
|
|
462
|
-
self.c2 ^= ((self.S_BOX[r1 >> 24] & 0xFF) << 24) & 0xFFFFFFFF
|
|
463
|
-
self.c2 ^= key[r][2] & 0xFFFFFFFF
|
|
464
|
-
self.c3 = (self.S_BOX[r3 & 0xFF] & 0xFF) & 0xFFFFFFFF
|
|
465
|
-
self.c3 ^= ((self.S_BOX[(r0 >> 8) & 0xFF] & 0xFF) << 8) & 0xFFFFFFFF
|
|
466
|
-
self.c3 ^= ((self.S_BOX[(r1 >> 16) & 0xFF] & 0xFF) << 16) & 0xFFFFFFFF
|
|
467
|
-
self.c3 ^= ((self.S_BOX[r2 >> 24] & 0xFF) << 24) & 0xFFFFFFFF
|
|
468
|
-
self.c3 ^= key[r][3] & 0xFFFFFFFF
|
|
469
|
-
|
|
470
|
-
def decryptBlock(self, key):
|
|
471
|
-
t0 = self.c0 ^ key[self.rounds][0]
|
|
472
|
-
t1 = self.c1 ^ key[self.rounds][1]
|
|
473
|
-
t2 = self.c2 ^ key[self.rounds][2]
|
|
474
|
-
r0 = r1 = r2 = 0
|
|
475
|
-
r3 = self.c3 ^ key[self.rounds][3]
|
|
476
|
-
r = self.rounds - 1
|
|
477
|
-
while r > 1:
|
|
478
|
-
r0 = (self.AES1_REVERSED[t0 & 255] & 0xFFFFFFFF) ^ self.shift(self.AES1_REVERSED[(r3 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t2 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t1 >> 24) & 255], 8) ^ key[r][0]
|
|
479
|
-
r1 = self.AES1_REVERSED[t1 & 255] ^ self.shift(self.AES1_REVERSED[(t0 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r3 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t2 >> 24) & 255], 8) ^ key[r][1]
|
|
480
|
-
r2 = self.AES1_REVERSED[t2 & 255] ^ self.shift(self.AES1_REVERSED[(t1 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t0 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r3 >> 24) & 255], 8) ^ key[r][2]
|
|
481
|
-
r3 = self.AES1_REVERSED[r3 & 255] ^ self.shift(self.AES1_REVERSED[(t2 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t1 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t0 >> 24) & 255], 8) ^ key[r][3]
|
|
482
|
-
r -= 1
|
|
483
|
-
t0 = self.AES1_REVERSED[r0 & 255] ^ self.shift(self.AES1_REVERSED[(r3 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r2 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r1 >> 24) & 255], 8) ^ key[r][0]
|
|
484
|
-
t1 = self.AES1_REVERSED[r1 & 255] ^ self.shift(self.AES1_REVERSED[(r0 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r3 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r2 >> 24) & 255], 8) ^ key[r][1]
|
|
485
|
-
t2 = self.AES1_REVERSED[r2 & 255] ^ self.shift(self.AES1_REVERSED[(r1 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r0 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r3 >> 24) & 255], 8) ^ key[r][2]
|
|
486
|
-
r3 = self.AES1_REVERSED[r3 & 255] ^ self.shift(self.AES1_REVERSED[(r2 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r1 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r0 >> 24) & 255], 8) ^ key[r][3]
|
|
487
|
-
r -= 1
|
|
488
|
-
r = 1
|
|
489
|
-
r0 = self.AES1_REVERSED[t0 & 255] ^ self.shift(self.AES1_REVERSED[(r3 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t2 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t1 >> 24) & 255], 8) ^ key[r][0]
|
|
490
|
-
r1 = self.AES1_REVERSED[t1 & 255] ^ self.shift(self.AES1_REVERSED[(t0 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r3 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t2 >> 24) & 255], 8) ^ key[r][1]
|
|
491
|
-
r2 = self.AES1_REVERSED[t2 & 255] ^ self.shift(self.AES1_REVERSED[(t1 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t0 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r3 >> 24) & 255], 8) ^ key[r][2]
|
|
492
|
-
r3 = self.AES1_REVERSED[r3 & 255] ^ self.shift(self.AES1_REVERSED[(t2 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t1 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t0 >> 24) & 255], 8) ^ key[r][3]
|
|
493
|
-
r = 0
|
|
494
|
-
self.c0 = (self.S_BOX_REVERSED[r0 & 255] & 0xFF) ^ ((((self.S_BOX_REVERSED[(r3 >> 8) & 255]) & 0xFF) << 8)) ^ ((((self.S_BOX_REVERSED[(r2 >> 16) & 255]) & 0xFF) << 16)) ^ ((((self.S_BOX_REVERSED[(r1 >> 24) & 255]) & 0xFF) << 24)) ^ key[r][0]
|
|
495
|
-
self.c1 = (self.S_BOX_REVERSED[r1 & 255] & 0xFF) ^ (((self.S_BOX_REVERSED[(r0 >> 8) & 255]) & 0xFF) << 8) ^ (((self.S_BOX_REVERSED[(r3 >> 16) & 255]) & 0xFF) << 16) ^ (((self.S_BOX_REVERSED[(r2 >> 24) & 255]) & 0xFF) << 24) ^ key[r][1]
|
|
496
|
-
self.c2 = (self.S_BOX_REVERSED[r2 & 255] & 0xFF) ^ (((self.S_BOX_REVERSED[(r1 >> 8) & 255]) & 0xFF) << 8) ^ (((self.S_BOX_REVERSED[(r0 >> 16) & 255]) & 0xFF) << 16) ^ (((self.S_BOX_REVERSED[(r3 >> 24) & 255]) & 0xFF) << 24) ^ key[r][2]
|
|
497
|
-
self.c3 = (self.S_BOX_REVERSED[r3 & 255] & 0xFF) ^ (((self.S_BOX_REVERSED[(r2 >> 8) & 255]) & 0xFF) << 8) ^ (((self.S_BOX_REVERSED[(r1 >> 16) & 255]) & 0xFF) << 16) ^ (((self.S_BOX_REVERSED[(r0 >> 24) & 255]) & 0xFF) << 24) ^ key[r][3]
|
|
498
|
-
|
|
499
|
-
def processBlock(self, input_, inOffset, forOutput, outOffset):
|
|
500
|
-
if inOffset + (32 / 2) > len(input_):
|
|
501
|
-
raise ValueError("input buffer too short")
|
|
502
|
-
if outOffset + (32 / 2) > len(forOutput):
|
|
503
|
-
raise ValueError("output buffer too short")
|
|
504
|
-
self.unPackBlock(input_, inOffset)
|
|
505
|
-
if self.encrypt:
|
|
506
|
-
self.encryptBlock(self.workingKey)
|
|
507
|
-
else:
|
|
508
|
-
self.decryptBlock(self.workingKey)
|
|
509
|
-
self.packBlock(forOutput, outOffset)
|
|
510
|
-
return self.BLOCK_SIZE
|
|
511
|
-
|
|
512
|
-
@classmethod
|
|
513
|
-
def bEToUInt32(cls, buff, offset):
|
|
514
|
-
value = (buff[offset] << 24)
|
|
515
|
-
value |= (buff[offset + 1] << 16) & 0xFF0000
|
|
516
|
-
value |= (buff[offset + 2] << 8) & 0xFF00
|
|
517
|
-
value |= buff[offset + 3] & 0xFF
|
|
518
|
-
return value
|
|
519
|
-
|
|
520
|
-
@classmethod
|
|
521
|
-
def shiftRight(cls, block, count):
|
|
522
|
-
bit = 0
|
|
523
|
-
i = 0
|
|
524
|
-
while i < 4:
|
|
525
|
-
b = block[i]
|
|
526
|
-
block[i] = (b >> count) | bit
|
|
527
|
-
bit = (b << (32 - count)) & 0xFFFFFFFF
|
|
528
|
-
i += 1
|
|
529
|
-
|
|
530
|
-
@classmethod
|
|
531
|
-
def multiplyP(cls, x):
|
|
532
|
-
lsb = (x[3] & 1) != 0
|
|
533
|
-
cls.shiftRight(x, 1)
|
|
534
|
-
if lsb:
|
|
535
|
-
x[0] ^= 0xe1000000
|
|
536
|
-
|
|
537
|
-
@classmethod
|
|
538
|
-
def getUint128(cls, buff):
|
|
539
|
-
us = [None] * 4
|
|
540
|
-
us[0] = cls.bEToUInt32(buff, 0)
|
|
541
|
-
us[1] = cls.bEToUInt32(buff, 4)
|
|
542
|
-
us[2] = cls.bEToUInt32(buff, 8)
|
|
543
|
-
us[3] = cls.bEToUInt32(buff, 12)
|
|
544
|
-
return us
|
|
545
|
-
|
|
546
|
-
@classmethod
|
|
547
|
-
def xor(cls, block, value):
|
|
548
|
-
pos = 0
|
|
549
|
-
while pos != 16:
|
|
550
|
-
block[pos] ^= value[pos]
|
|
551
|
-
pos += 1
|
|
552
|
-
|
|
553
|
-
@classmethod
|
|
554
|
-
def xor128(cls, block, value):
|
|
555
|
-
pos = 0
|
|
556
|
-
while pos != 4:
|
|
557
|
-
block[pos] ^= value[pos]
|
|
558
|
-
pos += 1
|
|
559
|
-
|
|
560
|
-
@classmethod
|
|
561
|
-
def multiplyP8(cls, x):
|
|
562
|
-
lsw = x[3]
|
|
563
|
-
cls.shiftRight(x, 8)
|
|
564
|
-
pos = 0
|
|
565
|
-
while pos != 8:
|
|
566
|
-
if (lsw & (1 << pos)) != 0:
|
|
567
|
-
x[0] ^= ((0xe1000000 >> (7 - pos)) & 0xFFFFFFFF)
|
|
568
|
-
pos += 1
|
|
569
|
-
|
|
570
|
-
def getGHash(self, b):
|
|
571
|
-
y = bytearray(16)
|
|
572
|
-
pos = 0
|
|
573
|
-
while pos < len(b):
|
|
574
|
-
x = bytearray(16)
|
|
575
|
-
cnt = min(len(b) - pos, 16)
|
|
576
|
-
x[0:cnt] = b[pos:pos + cnt]
|
|
577
|
-
self.xor(y, x)
|
|
578
|
-
self.multiplyH(y)
|
|
579
|
-
pos += 16
|
|
580
|
-
return y
|
|
581
|
-
|
|
582
|
-
@classmethod
|
|
583
|
-
def uInt32ToBE(cls, value, buff, offset):
|
|
584
|
-
buff[offset] = (value >> 24) & 0xFF
|
|
585
|
-
buff[offset + 1] = (value >> 16) & 0xFF
|
|
586
|
-
buff[offset + 2] = (value >> 8) & 0xFF
|
|
587
|
-
buff[offset + 3] = value & 0xFF
|
|
588
|
-
|
|
589
|
-
def multiplyH(self, value):
|
|
590
|
-
tmp = [0] * 4
|
|
591
|
-
pos = 0
|
|
592
|
-
while pos != 16:
|
|
593
|
-
m = self.mArray[pos + pos][value[pos] & 0x0f]
|
|
594
|
-
tmp[0] ^= m[0]
|
|
595
|
-
tmp[1] ^= m[1]
|
|
596
|
-
tmp[2] ^= m[2]
|
|
597
|
-
tmp[3] ^= m[3]
|
|
598
|
-
m = self.mArray[pos + pos + 1][(value[pos] & 0xf0) >> 4]
|
|
599
|
-
tmp[0] ^= m[0]
|
|
600
|
-
tmp[1] ^= m[1]
|
|
601
|
-
tmp[2] ^= m[2]
|
|
602
|
-
tmp[3] ^= m[3]
|
|
603
|
-
pos += 1
|
|
604
|
-
self.uInt32ToBE(tmp[0], value, 0)
|
|
605
|
-
self.uInt32ToBE(tmp[1], value, 4)
|
|
606
|
-
self.uInt32ToBE(tmp[2], value, 8)
|
|
607
|
-
self.uInt32ToBE(tmp[3], value, 12)
|
|
608
|
-
|
|
609
|
-
def init(self, value):
|
|
610
|
-
self.mArray[0] = [0] * 16
|
|
611
|
-
self.mArray[1] = [0] * 16
|
|
612
|
-
self.mArray[0][0] = [0] * 4
|
|
613
|
-
self.mArray[1][0] = [0] * 4
|
|
614
|
-
self.mArray[1][8] = self.getUint128(value)
|
|
615
|
-
tmp = []
|
|
616
|
-
pos = 4
|
|
617
|
-
while pos >= 1:
|
|
618
|
-
tmp = self.clone(self.mArray[1][pos + pos])
|
|
619
|
-
self.multiplyP(tmp)
|
|
620
|
-
self.mArray[1][pos] = tmp
|
|
621
|
-
pos >>= 1
|
|
622
|
-
tmp = self.clone(self.mArray[1][1])
|
|
623
|
-
self.multiplyP(tmp)
|
|
624
|
-
self.mArray[0][8] = tmp
|
|
625
|
-
pos = 4
|
|
626
|
-
while pos >= 1:
|
|
627
|
-
tmp = self.clone(self.mArray[0][pos + pos])
|
|
628
|
-
self.multiplyP(tmp)
|
|
629
|
-
self.mArray[0][pos] = tmp
|
|
630
|
-
pos >>= 1
|
|
631
|
-
pos1 = 0
|
|
632
|
-
while True:
|
|
633
|
-
pos2 = 2
|
|
634
|
-
while pos2 < 16:
|
|
635
|
-
k = 1
|
|
636
|
-
while k < pos2:
|
|
637
|
-
tmp = self.clone(self.mArray[pos1][pos2])
|
|
638
|
-
self.xor128(tmp, self.mArray[pos1][k])
|
|
639
|
-
self.mArray[pos1][pos2 + k] = tmp
|
|
640
|
-
k += 1
|
|
641
|
-
pos2 += pos2
|
|
642
|
-
pos1 += 1
|
|
643
|
-
if pos1 == 32:
|
|
644
|
-
return
|
|
645
|
-
if pos1 > 1:
|
|
646
|
-
self.mArray[pos1] = [0] * 16
|
|
647
|
-
self.mArray[pos1][0] = [0] * 4
|
|
648
|
-
pos = 8
|
|
649
|
-
while pos > 0:
|
|
650
|
-
tmp = self.clone(self.mArray[pos1 - 2][pos])
|
|
651
|
-
self.multiplyP8(tmp)
|
|
652
|
-
self.mArray[pos1][pos] = tmp
|
|
653
|
-
pos >>= 1
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
def gCTRBlock(self, buf, bufCount):
|
|
657
|
-
i = 15
|
|
658
|
-
while i >= 12:
|
|
659
|
-
self.counter[i] += 1
|
|
660
|
-
if self.counter[i] != 0:
|
|
661
|
-
break
|
|
662
|
-
i -= 1
|
|
663
|
-
tmp = bytearray(self.BLOCK_SIZE)
|
|
664
|
-
self.processBlock(self.counter, 0, tmp, 0)
|
|
665
|
-
if self.encrypt:
|
|
666
|
-
zeroes = bytearray(self.BLOCK_SIZE)
|
|
667
|
-
tmp[bufCount:self.BLOCK_SIZE] = zeroes[bufCount:self.BLOCK_SIZE]
|
|
668
|
-
hashBytes = tmp
|
|
669
|
-
else:
|
|
670
|
-
hashBytes = buf
|
|
671
|
-
pos = 0
|
|
672
|
-
while pos != bufCount:
|
|
673
|
-
tmp[pos] ^= buf[pos]
|
|
674
|
-
self.output.setUInt8(tmp[pos])
|
|
675
|
-
pos += 1
|
|
676
|
-
self.xor(self.s, hashBytes)
|
|
677
|
-
self.multiplyH(self.s)
|
|
678
|
-
self.totalLength += bufCount
|
|
679
|
-
|
|
680
|
-
@classmethod
|
|
681
|
-
def setPackLength(cls, length, buff, offset):
|
|
682
|
-
cls.uInt32ToBE(int((length >> 32)), buff, offset)
|
|
683
|
-
cls.uInt32ToBE(int(length), buff, offset + 4)
|
|
684
|
-
|
|
685
|
-
def reset(self):
|
|
686
|
-
self.s = self.getGHash(self.aad)
|
|
687
|
-
self.counter = self.clone(self.j0)
|
|
688
|
-
self.bytesRemaining = 0
|
|
689
|
-
self.totalLength = 0
|
|
690
|
-
|
|
691
|
-
@classmethod
|
|
692
|
-
def tagsEquals(cls, tag1, tag2):
|
|
693
|
-
pos = 0
|
|
694
|
-
while pos != 12:
|
|
695
|
-
if tag1[pos] != tag2[pos]:
|
|
696
|
-
return False
|
|
697
|
-
pos += 1
|
|
698
|
-
return True
|
|
699
|
-
|
|
700
|
-
def write(self, input_):
|
|
701
|
-
for it in input_:
|
|
702
|
-
self.bufBlock[self.bytesRemaining] = it
|
|
703
|
-
self.bytesRemaining += 1
|
|
704
|
-
if self.bytesRemaining == self.BLOCK_SIZE:
|
|
705
|
-
self.gCTRBlock(self.bufBlock, self.BLOCK_SIZE)
|
|
706
|
-
if not self.encrypt:
|
|
707
|
-
#System.arraycopy(self.bufBlock, self.BLOCK_SIZE,
|
|
708
|
-
#self.bufBlock, 0,)
|
|
709
|
-
self.bufBlock[0:len(self.tag)] = self.bufBlock[self.blockSize:self.blockSize + len(self.tag)]
|
|
710
|
-
self.bytesRemaining = 0
|
|
711
|
-
|
|
712
|
-
def flushFinalBlock(self):
|
|
713
|
-
if self.bytesRemaining > 0:
|
|
714
|
-
tmp = self.bufBlock[0:self.bytesRemaining]
|
|
715
|
-
self.gCTRBlock(tmp, self.bytesRemaining)
|
|
716
|
-
if self.security == Security.ENCRYPTION:
|
|
717
|
-
self.reset()
|
|
718
|
-
return self.output.array()
|
|
719
|
-
x = bytearray(16)
|
|
720
|
-
self.setPackLength(8 * len(self.aad), x, 0)
|
|
721
|
-
self.setPackLength(self.totalLength * 8, x, 8)
|
|
722
|
-
self.xor(self.s, x)
|
|
723
|
-
self.multiplyH(self.s)
|
|
724
|
-
generatedTag = bytearray(self.BLOCK_SIZE)
|
|
725
|
-
self.processBlock(self.j0, 0, generatedTag, 0)
|
|
726
|
-
self.xor(generatedTag, self.s)
|
|
727
|
-
if not self.encrypt:
|
|
728
|
-
if not self.tagsEquals(self.tag, generatedTag):
|
|
729
|
-
print(GXByteBuffer.hex(self.tag, False) + "-" + GXByteBuffer.hex(generatedTag, False))
|
|
730
|
-
raise ValueError("Decrypt failed. Invalid tag.")
|
|
731
|
-
else:
|
|
732
|
-
#Tag size is 12 bytes.
|
|
733
|
-
self.tag = generatedTag[0:12]
|
|
734
|
-
self.reset()
|
|
735
|
-
return self.output.array()
|
|
736
|
-
|
|
737
|
-
def generateKey(self, isEncrypt, key):
|
|
738
|
-
#Key length in words.
|
|
739
|
-
keyLen = int(len(key) / 4)
|
|
740
|
-
self.rounds = keyLen + 6
|
|
741
|
-
w = [[0 for x in range(4)] for y in range(self.rounds + 1)]
|
|
742
|
-
t = 0
|
|
743
|
-
i = 0
|
|
744
|
-
while i < len(key):
|
|
745
|
-
w[t >> 2][t & 3] = self.toUInt32(key, i)
|
|
746
|
-
i += 4
|
|
747
|
-
t += 1
|
|
748
|
-
k = (self.rounds + 1) << 2
|
|
749
|
-
i = keyLen
|
|
750
|
-
while i < k:
|
|
751
|
-
temp = w[(i - 1) >> 2][(i - 1) & 3]
|
|
752
|
-
if (i % keyLen) == 0:
|
|
753
|
-
temp = self.subWord(self.shift(temp, 8)) ^ (self.R_CON[int(i / keyLen) - 1] & 0xFF)
|
|
754
|
-
elif (keyLen > 6) and ((i % keyLen) == 4):
|
|
755
|
-
temp = self.subWord(temp)
|
|
756
|
-
w[i >> 2][i & 3] = w[(i - keyLen) >> 2][(i - keyLen) & 3] ^ temp
|
|
757
|
-
i += 1
|
|
758
|
-
if not isEncrypt:
|
|
759
|
-
j = 1
|
|
760
|
-
while j < self.rounds:
|
|
761
|
-
i = 0
|
|
762
|
-
while i < 4:
|
|
763
|
-
w[j][i] = self.imixCol(w[j][i])
|
|
764
|
-
i += 1
|
|
765
|
-
j += 1
|
|
766
|
-
return w
|
|
767
|
-
|
|
768
|
-
@classmethod
|
|
769
|
-
def galoisMultiply(cls, value):
|
|
770
|
-
if value >> 7 != 0:
|
|
771
|
-
value = value << 1
|
|
772
|
-
return (value ^ 0x1b) & 0xFF
|
|
773
|
-
|
|
774
|
-
return (value << 1) & 0xFF
|
|
775
|
-
# temp = (value >> 7) & 0xFF
|
|
776
|
-
# temp = temp & 0x1b
|
|
777
|
-
# return ((value << 1) ^ temp) & 0xFF
|
|
778
|
-
|
|
779
|
-
@classmethod
|
|
780
|
-
def aes1Encrypt(cls, data: bytearray, offset: int, secret: bytearray):
|
|
781
|
-
round_ = 0
|
|
782
|
-
i = 0
|
|
783
|
-
key = secret.copy()
|
|
784
|
-
while round_ < 10:
|
|
785
|
-
i = 0
|
|
786
|
-
while i < 16:
|
|
787
|
-
data[i + offset] = cls.S_BOX[(data[i + offset] ^ key[i]) & 0xFF]
|
|
788
|
-
i += 1
|
|
789
|
-
buf1 = data[1 + offset]
|
|
790
|
-
data[1 + offset] = data[5 + offset]
|
|
791
|
-
data[5 + offset] = data[9 + offset]
|
|
792
|
-
data[9 + offset] = data[13 + offset]
|
|
793
|
-
data[13 + offset] = buf1
|
|
794
|
-
buf1 = data[2 + offset]
|
|
795
|
-
buf2 = data[6 + offset]
|
|
796
|
-
data[2 + offset] = data[10 + offset]
|
|
797
|
-
data[6 + offset] = data[14 + offset]
|
|
798
|
-
data[10 + offset] = buf1
|
|
799
|
-
data[14 + offset] = buf2
|
|
800
|
-
buf1 = data[15 + offset]
|
|
801
|
-
data[15 + offset] = data[11 + offset]
|
|
802
|
-
data[11 + offset] = data[7 + offset]
|
|
803
|
-
data[7 + offset] = data[3 + offset]
|
|
804
|
-
data[3 + offset] = buf1
|
|
805
|
-
if round_ < 9:
|
|
806
|
-
i = 0
|
|
807
|
-
while i < 4:
|
|
808
|
-
buf4 = (i << 2) & 0xFF
|
|
809
|
-
buf1 = (data[buf4 + offset] ^ data[buf4 + 1 + offset] ^ data[buf4 + 2 + offset] ^ data[buf4 + 3 + offset]) & 0xFF
|
|
810
|
-
buf2 = data[buf4 + offset] & 0xFF
|
|
811
|
-
buf3 = (data[buf4 + offset] ^ data[buf4 + 1 + offset]) & 0xFF
|
|
812
|
-
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
813
|
-
data[buf4 + offset] = (data[buf4 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
814
|
-
buf3 = (data[buf4 + 1 + offset] ^ data[buf4 + 2 + offset]) & 0xFF
|
|
815
|
-
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
816
|
-
data[buf4 + 1 + offset] = (data[buf4 + 1 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
817
|
-
buf3 = (data[buf4 + 2 + offset] ^ data[buf4 + 3 + offset]) & 0xFF
|
|
818
|
-
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
819
|
-
data[buf4 + 2 + offset] = (data[buf4 + 2 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
820
|
-
buf3 = (data[buf4 + 3 + offset] ^ buf2) & 0xFF
|
|
821
|
-
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
822
|
-
data[buf4 + 3 + offset] = (data[buf4 + 3 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
823
|
-
i += 1
|
|
824
|
-
key[0] = (cls.S_BOX[key[13] & 0xFF] ^ key[0] ^ cls.R_CON[round_]) & 0xFF
|
|
825
|
-
key[1] = (cls.S_BOX[key[14] & 0xFF] ^ key[1]) & 0xFF
|
|
826
|
-
key[2] = (cls.S_BOX[key[15] & 0xFF] ^ key[2]) & 0xFF
|
|
827
|
-
key[3] = (cls.S_BOX[key[12] & 0xFF] ^ key[3]) & 0xFF
|
|
828
|
-
i = 4
|
|
829
|
-
while i < 16:
|
|
830
|
-
key[i] = (key[i] ^ key[i - 4]) & 0xFF
|
|
831
|
-
i += 1
|
|
832
|
-
round_ += 1
|
|
833
|
-
i = 0
|
|
834
|
-
while i < 16:
|
|
835
|
-
data[i + offset] = (data[i + offset] ^ key[i])
|
|
836
|
-
i += 1
|
|
837
|
-
|
|
838
|
-
def encryptAes(self, data):
|
|
839
|
-
n = len(data) / 8
|
|
840
|
-
if (n * 8) != len(data):
|
|
841
|
-
raise ValueError("Invalid data.")
|
|
842
|
-
iv = bytearray([0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6])
|
|
843
|
-
block = bytearray(len(data) + len(iv))
|
|
844
|
-
buf = bytearray(8 + len(iv))
|
|
845
|
-
block[0:len(self.IV)] = self.IV[0:len(self.IV)]
|
|
846
|
-
block[len(self.IV):len(self.IV) + len(data)] = data[0:len(data)]
|
|
847
|
-
j = 0
|
|
848
|
-
while j != 6:
|
|
849
|
-
i = 1
|
|
850
|
-
while i <= n:
|
|
851
|
-
buf[0:len(self.IV)] = block[0: len(self.IV)]
|
|
852
|
-
buf[len(self.IV):8 + len(self.IV)] = block[8 * i:8 * i + 8]
|
|
853
|
-
self.processBlock(buf, 0, buf, 0)
|
|
854
|
-
t = int(n * j + i)
|
|
855
|
-
k = 1
|
|
856
|
-
while t != 0:
|
|
857
|
-
v = int(t)
|
|
858
|
-
buf[len(self.IV) - k] ^= v
|
|
859
|
-
t = int(t >> 8)
|
|
860
|
-
k += 1
|
|
861
|
-
block[0:8] = buf[0:8]
|
|
862
|
-
block[8 * i:8 * i + 8] = buf[8:16]
|
|
863
|
-
i += 1
|
|
864
|
-
j += 1
|
|
865
|
-
return block
|
|
866
|
-
|
|
867
|
-
def decryptAes(self, input_):
|
|
868
|
-
n = len(input_) / 8
|
|
869
|
-
if (n * 8) != len(input_):
|
|
870
|
-
raise ValueError("Invalid data.")
|
|
871
|
-
iv = bytearray([0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6])
|
|
872
|
-
if len(input_) > len(iv):
|
|
873
|
-
block = bytearray(len(input_) - len(iv))
|
|
874
|
-
else:
|
|
875
|
-
block = bytearray(len(iv))
|
|
876
|
-
a = bytearray(len(iv))
|
|
877
|
-
buf = bytearray(8 + len(iv))
|
|
878
|
-
a[0:] = input_[0:len(iv)]
|
|
879
|
-
block[0:] = input_[len(iv):len(input_)]
|
|
880
|
-
n = n - 1
|
|
881
|
-
if n == 0:
|
|
882
|
-
n = 1
|
|
883
|
-
j = 5
|
|
884
|
-
while j >= 0:
|
|
885
|
-
i = n
|
|
886
|
-
while i >= 1:
|
|
887
|
-
buf[0:len(iv)] = a[0:len(iv)]
|
|
888
|
-
buf[len(iv):8 + len(iv)] = block[8 * int(i - 1):8 * int(i)]
|
|
889
|
-
t = n * j + i
|
|
890
|
-
k = 1
|
|
891
|
-
while t != 0:
|
|
892
|
-
v = int(t)
|
|
893
|
-
buf[len(self.IV)] ^= v
|
|
894
|
-
t = int((int(t) >> 8))
|
|
895
|
-
k += 1
|
|
896
|
-
self.processBlock(buf, 0, buf, 0)
|
|
897
|
-
a[0:] = buf[0:8]
|
|
898
|
-
block[8:16] = buf[8 * (i - 1):8*i]
|
|
899
|
-
i -= 1
|
|
900
|
-
j -= 1
|
|
901
|
-
if a != self.IV:
|
|
902
|
-
raise ValueError("Invalid data")
|
|
903
|
-
return block
|
|
904
|
-
|
|
905
|
-
@classmethod
|
|
906
|
-
def aes1Decrypt(cls, data, secret):
|
|
907
|
-
buf1 = 0
|
|
908
|
-
buf2 = 0
|
|
909
|
-
buf3 = 0
|
|
910
|
-
round_ = 0
|
|
911
|
-
i = 0
|
|
912
|
-
buf4 = 0
|
|
913
|
-
key = secret[0:]
|
|
914
|
-
while round_ < 10:
|
|
915
|
-
key[0] = int((cls.S_BOX[key[13] & 0xFF] ^ key[0] ^ cls.R_CON[round_]))
|
|
916
|
-
key[1] = int((cls.S_BOX[key[14] & 0xFF] ^ key[1]))
|
|
917
|
-
key[2] = int((cls.S_BOX[key[15] & 0xFF] ^ key[2]))
|
|
918
|
-
key[3] = int((cls.S_BOX[key[12] & 0xFF] ^ key[3]))
|
|
919
|
-
while i < 16:
|
|
920
|
-
key[i] = int((key[i] ^ key[i - 4]))
|
|
921
|
-
i += 1
|
|
922
|
-
round_ += 1
|
|
923
|
-
while i < 16:
|
|
924
|
-
data[i] = int((data[i] ^ key[i]))
|
|
925
|
-
i += 1
|
|
926
|
-
while round_ < 10:
|
|
927
|
-
while i > 3:
|
|
928
|
-
key[i] = int((key[i] ^ key[i - 4]))
|
|
929
|
-
i -= 1
|
|
930
|
-
key[0] = int((cls.S_BOX[key[13] & 0xFF] ^ key[0] ^ cls.R_CON[9 - round_]))
|
|
931
|
-
key[1] = int((cls.S_BOX[key[14] & 0xFF] ^ key[1]))
|
|
932
|
-
key[2] = int((cls.S_BOX[key[15] & 0xFF] ^ key[2]))
|
|
933
|
-
key[3] = int((cls.S_BOX[key[12] & 0xFF] ^ key[3]))
|
|
934
|
-
if round_ > 0:
|
|
935
|
-
while i < 4:
|
|
936
|
-
buf4 = (i << 2) & 0xFF
|
|
937
|
-
buf1 = cls.galoisMultiply(cls.galoisMultiply(data[buf4] ^ data[buf4 + 2]))
|
|
938
|
-
buf2 = cls.galoisMultiply(cls.galoisMultiply(data[buf4 + 1] ^ data[buf4 + 3]))
|
|
939
|
-
data[buf4] ^= buf1
|
|
940
|
-
data[buf4 + 1] ^= buf2
|
|
941
|
-
data[buf4 + 2] ^= buf1
|
|
942
|
-
data[buf4 + 3] ^= buf2
|
|
943
|
-
buf1 = int((data[buf4] ^ data[buf4 + 1] ^ data[buf4 + 2] ^ data[buf4 + 3]))
|
|
944
|
-
buf2 = data[buf4]
|
|
945
|
-
buf3 = int((data[buf4] ^ data[buf4 + 1]))
|
|
946
|
-
buf3 = cls.galoisMultiply(buf3)
|
|
947
|
-
data[buf4] = int((data[buf4] ^ buf3 ^ buf1))
|
|
948
|
-
buf3 = int((data[buf4 + 1] ^ data[buf4 + 2]))
|
|
949
|
-
buf3 = cls.galoisMultiply(buf3)
|
|
950
|
-
data[buf4 + 1] = int((data[buf4 + 1] ^ buf3 ^ buf1))
|
|
951
|
-
buf3 = int((data[buf4 + 2] ^ data[buf4 + 3]))
|
|
952
|
-
buf3 = cls.galoisMultiply(buf3)
|
|
953
|
-
data[buf4 + 2] = int((data[buf4 + 2] ^ buf3 ^ buf1))
|
|
954
|
-
buf3 = int((data[buf4 + 3] ^ buf2))
|
|
955
|
-
buf3 = cls.galoisMultiply(buf3)
|
|
956
|
-
data[buf4 + 3] = int((data[buf4 + 3] ^ buf3 ^ buf1))
|
|
957
|
-
i += 1
|
|
958
|
-
buf1 = data[13]
|
|
959
|
-
data[13] = data[9]
|
|
960
|
-
data[9] = data[5]
|
|
961
|
-
data[5] = data[1]
|
|
962
|
-
data[1] = buf1
|
|
963
|
-
buf1 = data[10]
|
|
964
|
-
buf2 = data[14]
|
|
965
|
-
data[10] = data[2]
|
|
966
|
-
data[14] = data[6]
|
|
967
|
-
data[2] = buf1
|
|
968
|
-
data[6] = buf2
|
|
969
|
-
buf1 = data[3]
|
|
970
|
-
data[3] = data[7]
|
|
971
|
-
data[7] = data[11]
|
|
972
|
-
data[11] = data[15]
|
|
973
|
-
data[15] = buf1
|
|
974
|
-
while i < 16:
|
|
975
|
-
data[i] = int((cls.S_BOX_REVERSED[data[i] & 0xFF] ^ key[i]))
|
|
976
|
-
i += 1
|
|
977
|
-
round_ += 1
|
|
1
|
+
from __future__ import print_function
|
|
2
|
+
from .GXByteBuffer import GXByteBuffer
|
|
3
|
+
from .enums.Security import Security
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class GXDLMSChipperingStream:
|
|
7
|
+
"""
|
|
8
|
+
Implements GMAC. This class is based to this doc:
|
|
9
|
+
http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# Consts.
|
|
13
|
+
BLOCK_SIZE = 16
|
|
14
|
+
TAG_SIZE = 0x10
|
|
15
|
+
IV = [0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6]
|
|
16
|
+
|
|
17
|
+
#schedule Vector (powers of x).
|
|
18
|
+
R_CON = (0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,\
|
|
19
|
+
0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,\
|
|
20
|
+
0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,\
|
|
21
|
+
0xc5, 0x91)
|
|
22
|
+
|
|
23
|
+
#S box
|
|
24
|
+
@classmethod
|
|
25
|
+
def aes1Encrypt(cls, data: bytearray, offset: int, secret: bytearray):
|
|
26
|
+
round_ = 0
|
|
27
|
+
i = 0
|
|
28
|
+
key = secret.copy()
|
|
29
|
+
while round_ < 10:
|
|
30
|
+
i = 0
|
|
31
|
+
while i < 16:
|
|
32
|
+
data[i + offset] = cls.S_BOX[(data[i + offset] ^ key[i]) & 0xFF]
|
|
33
|
+
i += 1
|
|
34
|
+
buf1 = data[1 + offset]
|
|
35
|
+
data[1 + offset] = data[5 + offset]
|
|
36
|
+
data[5 + offset] = data[9 + offset]
|
|
37
|
+
data[9 + offset] = data[13 + offset]
|
|
38
|
+
data[13 + offset] = buf1
|
|
39
|
+
buf1 = data[2 + offset]
|
|
40
|
+
buf2 = data[6 + offset]
|
|
41
|
+
data[2 + offset] = data[10 + offset]
|
|
42
|
+
data[6 + offset] = data[14 + offset]
|
|
43
|
+
data[10 + offset] = buf1
|
|
44
|
+
data[14 + offset] = buf2
|
|
45
|
+
buf1 = data[15 + offset]
|
|
46
|
+
data[15 + offset] = data[11 + offset]
|
|
47
|
+
data[11 + offset] = data[7 + offset]
|
|
48
|
+
data[7 + offset] = data[3 + offset]
|
|
49
|
+
data[3 + offset] = buf1
|
|
50
|
+
if round_ < 9:
|
|
51
|
+
i = 0
|
|
52
|
+
while i < 4:
|
|
53
|
+
buf4 = (i << 2) & 0xFF
|
|
54
|
+
buf1 = (data[buf4 + offset] ^ data[buf4 + 1 + offset] ^ data[buf4 + 2 + offset] ^ data[buf4 + 3 + offset]) & 0xFF
|
|
55
|
+
buf2 = data[buf4 + offset] & 0xFF
|
|
56
|
+
buf3 = (data[buf4 + offset] ^ data[buf4 + 1 + offset]) & 0xFF
|
|
57
|
+
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
58
|
+
data[buf4 + offset] = (data[buf4 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
59
|
+
buf3 = (data[buf4 + 1 + offset] ^ data[buf4 + 2 + offset]) & 0xFF
|
|
60
|
+
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
61
|
+
data[buf4 + 1 + offset] = (data[buf4 + 1 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
62
|
+
buf3 = (data[buf4 + 2 + offset] ^ data[buf4 + 3 + offset]) & 0xFF
|
|
63
|
+
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
64
|
+
data[buf4 + 2 + offset] = (data[buf4 + 2 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
65
|
+
buf3 = (data[buf4 + 3 + offset] ^ buf2) & 0xFF
|
|
66
|
+
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
67
|
+
data[buf4 + 3 + offset] = (data[buf4 + 3 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
68
|
+
i += 1
|
|
69
|
+
key[0] = (cls.S_BOX[key[13] & 0xFF] ^ key[0] ^ cls.R_CON[round_]) & 0xFF
|
|
70
|
+
key[1] = (cls.S_BOX[key[14] & 0xFF] ^ key[1]) & 0xFF
|
|
71
|
+
key[2] = (cls.S_BOX[key[15] & 0xFF] ^ key[2]) & 0xFF
|
|
72
|
+
key[3] = (cls.S_BOX[key[12] & 0xFF] ^ key[3]) & 0xFF
|
|
73
|
+
i = 4
|
|
74
|
+
while i < 16:
|
|
75
|
+
key[i] = (key[i] ^ key[i - 4]) & 0xFF
|
|
76
|
+
i += 1
|
|
77
|
+
round_ += 1
|
|
78
|
+
i = 0
|
|
79
|
+
while i < 16:
|
|
80
|
+
data[i + offset] = (data[i + offset] ^ key[i])
|
|
81
|
+
i += 1
|
|
82
|
+
|
|
83
|
+
S_BOX = (0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,\
|
|
84
|
+
0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82,\
|
|
85
|
+
0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF,\
|
|
86
|
+
0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F,\
|
|
87
|
+
0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,\
|
|
88
|
+
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12,\
|
|
89
|
+
0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A,\
|
|
90
|
+
0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3,\
|
|
91
|
+
0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,\
|
|
92
|
+
0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF,\
|
|
93
|
+
0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,\
|
|
94
|
+
0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D,\
|
|
95
|
+
0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,\
|
|
96
|
+
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7,\
|
|
97
|
+
0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC,\
|
|
98
|
+
0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E,\
|
|
99
|
+
0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,\
|
|
100
|
+
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8,\
|
|
101
|
+
0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA,\
|
|
102
|
+
0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6,\
|
|
103
|
+
0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,\
|
|
104
|
+
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35,\
|
|
105
|
+
0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,\
|
|
106
|
+
0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55,\
|
|
107
|
+
0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,\
|
|
108
|
+
0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16)
|
|
109
|
+
|
|
110
|
+
#Inverse sbox
|
|
111
|
+
S_BOX_REVERSED = (0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5,\
|
|
112
|
+
0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c,\
|
|
113
|
+
0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43,\
|
|
114
|
+
0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6,\
|
|
115
|
+
0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3,\
|
|
116
|
+
0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76,\
|
|
117
|
+
0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6,\
|
|
118
|
+
0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d,\
|
|
119
|
+
0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9,\
|
|
120
|
+
0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90,\
|
|
121
|
+
0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58,\
|
|
122
|
+
0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca,\
|
|
123
|
+
0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a,\
|
|
124
|
+
0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97,\
|
|
125
|
+
0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74,\
|
|
126
|
+
0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c,\
|
|
127
|
+
0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5,\
|
|
128
|
+
0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc,\
|
|
129
|
+
0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0,\
|
|
130
|
+
0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88,\
|
|
131
|
+
0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec,\
|
|
132
|
+
0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d,\
|
|
133
|
+
0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b,\
|
|
134
|
+
0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83,\
|
|
135
|
+
0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6,\
|
|
136
|
+
0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d)
|
|
137
|
+
|
|
138
|
+
#Rijndael (AES) Encryption fast table.
|
|
139
|
+
AES = (0xa56363c6, 0x847c7cf8, 0x997777ee,\
|
|
140
|
+
0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,\
|
|
141
|
+
0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7,\
|
|
142
|
+
0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f,\
|
|
143
|
+
0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e,\
|
|
144
|
+
0x0bf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,\
|
|
145
|
+
0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775,\
|
|
146
|
+
0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e,\
|
|
147
|
+
0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, 0x34e5e5d1,\
|
|
148
|
+
0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,\
|
|
149
|
+
0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830,\
|
|
150
|
+
0xa1969637, 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224,\
|
|
151
|
+
0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f,\
|
|
152
|
+
0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,\
|
|
153
|
+
0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4,\
|
|
154
|
+
0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd,\
|
|
155
|
+
0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000,\
|
|
156
|
+
0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,\
|
|
157
|
+
0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94,\
|
|
158
|
+
0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5,\
|
|
159
|
+
0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366,\
|
|
160
|
+
0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,\
|
|
161
|
+
0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2,\
|
|
162
|
+
0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21,\
|
|
163
|
+
0x48383870, 0x04f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf,\
|
|
164
|
+
0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,\
|
|
165
|
+
0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe,\
|
|
166
|
+
0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755,\
|
|
167
|
+
0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932,\
|
|
168
|
+
0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,\
|
|
169
|
+
0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 0xca46468c,\
|
|
170
|
+
0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc,\
|
|
171
|
+
0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74,\
|
|
172
|
+
0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,\
|
|
173
|
+
0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139,\
|
|
174
|
+
0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b,\
|
|
175
|
+
0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c,\
|
|
176
|
+
0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,\
|
|
177
|
+
0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f,\
|
|
178
|
+
0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657,\
|
|
179
|
+
0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8,\
|
|
180
|
+
0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,\
|
|
181
|
+
0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890,\
|
|
182
|
+
0x05030306, 0x01f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a,\
|
|
183
|
+
0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a,\
|
|
184
|
+
0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,\
|
|
185
|
+
0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d,\
|
|
186
|
+
0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa,\
|
|
187
|
+
0x78282850, 0x7adfdfa5, 0x8f8c8c03, 0xf8a1a159, 0x80898909,\
|
|
188
|
+
0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,\
|
|
189
|
+
0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b,\
|
|
190
|
+
0xfc5454a8, 0xd6bbbb6d, 0x3a16162c)
|
|
191
|
+
|
|
192
|
+
AES1_REVERSED = (0x50a7f451, 0x5365417e,\
|
|
193
|
+
0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac,\
|
|
194
|
+
0x9303e34b, 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5,\
|
|
195
|
+
0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de,\
|
|
196
|
+
0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81,\
|
|
197
|
+
0xa397468d, 0xc6f9d36b, 0xe75f8f03, 0x959c9215, 0xeb7a6dbf,\
|
|
198
|
+
0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,\
|
|
199
|
+
0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be,\
|
|
200
|
+
0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 0x184adf63, 0x82311ae5,\
|
|
201
|
+
0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe,\
|
|
202
|
+
0x942b08f9, 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52,\
|
|
203
|
+
0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x0728ebb2,\
|
|
204
|
+
0x03c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23,\
|
|
205
|
+
0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3,\
|
|
206
|
+
0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,\
|
|
207
|
+
0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b,\
|
|
208
|
+
0xaaef6040, 0x069f715e, 0x51106ebd, 0xf98a213e, 0x3d06dd96,\
|
|
209
|
+
0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604,\
|
|
210
|
+
0xff155060, 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967,\
|
|
211
|
+
0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 0x470a7ca1,\
|
|
212
|
+
0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32,\
|
|
213
|
+
0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d,\
|
|
214
|
+
0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,\
|
|
215
|
+
0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080,\
|
|
216
|
+
0xa220dc61, 0x694b775a, 0x161a121c, 0x0aba93e2, 0xe52aa0c0,\
|
|
217
|
+
0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d,\
|
|
218
|
+
0xc8a91e14, 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3,\
|
|
219
|
+
0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b,\
|
|
220
|
+
0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342,\
|
|
221
|
+
0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae,\
|
|
222
|
+
0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,\
|
|
223
|
+
0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8,\
|
|
224
|
+
0x1a3ff0a0, 0xd82c7d56, 0xef903322, 0xc74e4987, 0xc1d138d9,\
|
|
225
|
+
0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da,\
|
|
226
|
+
0xa4bfad3f, 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54,\
|
|
227
|
+
0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f,\
|
|
228
|
+
0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810,\
|
|
229
|
+
0x6e639ce8, 0x7bbb3bdb, 0x097826cd, 0xf418596e, 0x01b79aec,\
|
|
230
|
+
0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,\
|
|
231
|
+
0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431,\
|
|
232
|
+
0x31233f2a, 0x3094a5c6, 0xc066a235, 0x37bc4e74, 0xa6ca82fc,\
|
|
233
|
+
0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0x0e50cd7f,\
|
|
234
|
+
0x2ff69117, 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4,\
|
|
235
|
+
0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x04ea5e9d,\
|
|
236
|
+
0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92,\
|
|
237
|
+
0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859,\
|
|
238
|
+
0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,\
|
|
239
|
+
0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753,\
|
|
240
|
+
0x5baafd5f, 0x146f3ddf, 0x86db4478, 0x81f3afca, 0x3ec468b9,\
|
|
241
|
+
0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28,\
|
|
242
|
+
0x41950dff, 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664,\
|
|
243
|
+
0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0)
|
|
244
|
+
|
|
245
|
+
blockSize = 16
|
|
246
|
+
|
|
247
|
+
#
|
|
248
|
+
# * Constructor.
|
|
249
|
+
# *
|
|
250
|
+
# * @param forSecurity
|
|
251
|
+
# * Used security level.
|
|
252
|
+
# * @param forEncrypt
|
|
253
|
+
# * @param blockCipherKey
|
|
254
|
+
# * @param forAad
|
|
255
|
+
# * @param iv
|
|
256
|
+
# * @param forTag
|
|
257
|
+
#
|
|
258
|
+
def __init__(self, forSecurity, forEncrypt, blockCipherKey, forAad, iv, forTag):
|
|
259
|
+
self.security = forSecurity
|
|
260
|
+
self.tag = forTag
|
|
261
|
+
if not self.tag:
|
|
262
|
+
# Tag size is 12 bytes.
|
|
263
|
+
self.tag = bytearray(12)
|
|
264
|
+
elif len(self.tag) != 12:
|
|
265
|
+
raise ValueError("Invalid tag.")
|
|
266
|
+
self.encrypt = forEncrypt
|
|
267
|
+
self.workingKey = self.generateKey(forEncrypt, blockCipherKey)
|
|
268
|
+
if self.encrypt:
|
|
269
|
+
bufLength = GXDLMSChipperingStream.BLOCK_SIZE
|
|
270
|
+
else:
|
|
271
|
+
bufLength = (GXDLMSChipperingStream.BLOCK_SIZE + GXDLMSChipperingStream.TAG_SIZE)
|
|
272
|
+
self.bufBlock = bytearray(bufLength)
|
|
273
|
+
self.aad = forAad
|
|
274
|
+
self.h = bytearray(GXDLMSChipperingStream.BLOCK_SIZE)
|
|
275
|
+
if iv:
|
|
276
|
+
self.processBlock(self.h, 0, self.h, 0)
|
|
277
|
+
self.mArray = [[None] * 32] * 32
|
|
278
|
+
self.init(self.h)
|
|
279
|
+
self.j0 = bytearray(16)
|
|
280
|
+
self.j0[0:len(iv)] = iv[0:]
|
|
281
|
+
self.j0[15] = 0x01
|
|
282
|
+
if self.aad:
|
|
283
|
+
self.s = self.getGHash(self.aad)
|
|
284
|
+
if iv:
|
|
285
|
+
self.counter = self.clone(self.j0)
|
|
286
|
+
self.bytesRemaining = 0
|
|
287
|
+
self.totalLength = 0
|
|
288
|
+
self.output = GXByteBuffer()
|
|
289
|
+
self.c0 = self.c1 = self.c2 = self.c3 = 0
|
|
290
|
+
self.blockSize = 16
|
|
291
|
+
|
|
292
|
+
@classmethod
|
|
293
|
+
def clone(cls, value):
|
|
294
|
+
""" Clone byte array. """
|
|
295
|
+
tmp = value[0:]
|
|
296
|
+
return tmp
|
|
297
|
+
|
|
298
|
+
#
|
|
299
|
+
# * Convert byte array to Little Endian.
|
|
300
|
+
# *
|
|
301
|
+
# * @param data
|
|
302
|
+
# * @param offset
|
|
303
|
+
# * @return
|
|
304
|
+
#
|
|
305
|
+
@classmethod
|
|
306
|
+
def toUInt32(cls, value, offset):
|
|
307
|
+
tmp = value[offset] & 0xFF
|
|
308
|
+
tmp |= (value[offset + 1] << 8) & 0xFF00
|
|
309
|
+
tmp |= (value[offset + 2] << 16) & 0xFF0000
|
|
310
|
+
tmp |= (value[offset + 3] << 24) & 0xFF000000
|
|
311
|
+
return tmp
|
|
312
|
+
|
|
313
|
+
@classmethod
|
|
314
|
+
def subWord(cls, value):
|
|
315
|
+
tmp = cls.S_BOX[value & 0xFF] & 0xFF
|
|
316
|
+
tmp |= (((cls.S_BOX[(value >> 8) & 0xFF]) & 0xFF) << 8) & 0xFF00
|
|
317
|
+
tmp |= (((cls.S_BOX[(value >> 16) & 0xFF]) & 0xFF) << 16) & 0xFF0000
|
|
318
|
+
tmp |= (((cls.S_BOX[(value >> 24) & 0xFF]) & 0xFF) << 24) & 0xFF000000
|
|
319
|
+
return tmp
|
|
320
|
+
|
|
321
|
+
@classmethod
|
|
322
|
+
def shift(cls, value, shift):
|
|
323
|
+
"""
|
|
324
|
+
Shift value.
|
|
325
|
+
"""
|
|
326
|
+
return (value >> shift) | (value << (32 - shift)) & 0xFFFFFFFF
|
|
327
|
+
|
|
328
|
+
#
|
|
329
|
+
# * Initialise the key schedule from the user supplied key.
|
|
330
|
+
# *
|
|
331
|
+
# * @return
|
|
332
|
+
#
|
|
333
|
+
@classmethod
|
|
334
|
+
def starX(cls, value):
|
|
335
|
+
m1 = 0x80808080
|
|
336
|
+
m2 = 0x7f7f7f7f
|
|
337
|
+
m3 = 0x0000001b
|
|
338
|
+
return ((value & m2) << 1) ^ (((value & m1) >> 7) * m3)
|
|
339
|
+
|
|
340
|
+
def imixCol(self, x):
|
|
341
|
+
f2 = self.starX(x)
|
|
342
|
+
f4 = self.starX(f2)
|
|
343
|
+
f8 = self.starX(f4)
|
|
344
|
+
f9 = x ^ f8
|
|
345
|
+
return f2 ^ f4 ^ f8 ^ self.shift(f2 ^ f9, 8) ^ self.shift(f4 ^ f9, 16) ^ self.shift(f9, 24)
|
|
346
|
+
|
|
347
|
+
#
|
|
348
|
+
# * Get bytes from UIn32.
|
|
349
|
+
# *
|
|
350
|
+
# * @param value
|
|
351
|
+
# * @param data
|
|
352
|
+
# * @param offset
|
|
353
|
+
#
|
|
354
|
+
@classmethod
|
|
355
|
+
def getUInt32(cls, value, data, offset):
|
|
356
|
+
data[offset] = value & 0xFF
|
|
357
|
+
data[offset + 1] = (value >> 8) & 0xFF
|
|
358
|
+
data[offset + 2] = (value >> 16) & 0xFF
|
|
359
|
+
data[offset + 3] = (value >> 24) & 0xFF
|
|
360
|
+
|
|
361
|
+
def unPackBlock(self, bytes_, offset):
|
|
362
|
+
self.c0 = self.toUInt32(bytes_, offset)
|
|
363
|
+
self.c1 = self.toUInt32(bytes_, offset + 4)
|
|
364
|
+
self.c2 = self.toUInt32(bytes_, offset + 8)
|
|
365
|
+
self.c3 = self.toUInt32(bytes_, offset + 12)
|
|
366
|
+
|
|
367
|
+
def packBlock(self, bytes_, offset):
|
|
368
|
+
self.getUInt32(self.c0, bytes_, offset)
|
|
369
|
+
self.getUInt32(self.c1, bytes_, offset + 4)
|
|
370
|
+
self.getUInt32(self.c2, bytes_, offset + 8)
|
|
371
|
+
self.getUInt32(self.c3, bytes_, offset + 12)
|
|
372
|
+
|
|
373
|
+
#
|
|
374
|
+
# * Encrypt data block.
|
|
375
|
+
# *
|
|
376
|
+
# * @param key
|
|
377
|
+
#
|
|
378
|
+
def encryptBlock(self, key):
|
|
379
|
+
r = 1
|
|
380
|
+
self.c0 ^= key[0][0]
|
|
381
|
+
self.c1 ^= key[0][1]
|
|
382
|
+
self.c2 ^= key[0][2]
|
|
383
|
+
self.c3 ^= key[0][3]
|
|
384
|
+
while r < self.rounds - 1:
|
|
385
|
+
r0 = (self.AES[self.c0 & 0xFF] & 0xFFFFFFFF)
|
|
386
|
+
r0 ^= (self.shift(self.AES[(self.c1 >> 8) & 0xFF], 24) & 0xFFFFFFFF)
|
|
387
|
+
r0 ^= (self.shift(self.AES[(self.c2 >> 16) & 0xFF], 16) & 0xFFFFFFFF)
|
|
388
|
+
r0 ^= (self.shift(self.AES[(self.c3 >> 24) & 0xFF], 8) & 0xFFFFFFFF)
|
|
389
|
+
r0 ^= (key[r][0] & 0xFFFFFFFF)
|
|
390
|
+
r1 = (self.AES[self.c1 & 0xFF] & 0xFFFFFFFF)
|
|
391
|
+
r1 ^= self.shift(self.AES[(self.c2 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
392
|
+
r1 ^= self.shift(self.AES[(self.c3 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
393
|
+
r1 ^= self.shift(self.AES[(self.c0 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
394
|
+
r1 ^= key[r][1] & 0xFFFFFFFF
|
|
395
|
+
r2 = self.AES[self.c2 & 0xFF] & 0xFFFFFFFF
|
|
396
|
+
r2 ^= self.shift(self.AES[(self.c3 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
397
|
+
r2 ^= self.shift(self.AES[(self.c0 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
398
|
+
r2 ^= self.shift(self.AES[(self.c1 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
399
|
+
r2 ^= key[r][2] & 0xFFFFFFFF
|
|
400
|
+
r3 = self.AES[self.c3 & 0xFF] & 0xFFFFFFFF
|
|
401
|
+
r3 ^= self.shift(self.AES[(self.c0 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
402
|
+
r3 ^= self.shift(self.AES[(self.c1 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
403
|
+
r3 ^= self.shift(self.AES[(self.c2 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
404
|
+
r3 ^= key[r][3] & 0xFFFFFFFF
|
|
405
|
+
r = r + 1
|
|
406
|
+
self.c0 = self.AES[r0 & 0xFF] & 0xFFFFFFFF
|
|
407
|
+
self.c0 ^= self.shift(self.AES[(r1 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
408
|
+
self.c0 ^= self.shift(self.AES[(r2 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
409
|
+
self.c0 ^= self.shift(self.AES[(r3 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
410
|
+
self.c0 ^= key[r][0] & 0xFFFFFFFF
|
|
411
|
+
self.c1 = self.AES[r1 & 0xFF] & 0xFFFFFFFF
|
|
412
|
+
self.c1 ^= self.shift(self.AES[(r2 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
413
|
+
self.c1 ^= self.shift(self.AES[(r3 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
414
|
+
self.c1 ^= self.shift(self.AES[(r0 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
415
|
+
self.c1 ^= key[r][1] & 0xFFFFFFFF
|
|
416
|
+
self.c2 = self.AES[r2 & 0xFF] & 0xFFFFFFFF
|
|
417
|
+
self.c2 ^= self.shift(self.AES[(r3 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
418
|
+
self.c2 ^= self.shift(self.AES[(r0 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
419
|
+
self.c2 ^= self.shift(self.AES[(r1 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
420
|
+
self.c2 ^= key[r][2] & 0xFFFFFFFF
|
|
421
|
+
self.c3 = self.AES[r3 & 0xFF] & 0xFFFFFFFF
|
|
422
|
+
self.c3 ^= self.shift(self.AES[(r0 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
423
|
+
self.c3 ^= self.shift(self.AES[(r1 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
424
|
+
self.c3 ^= self.shift(self.AES[(r2 >> 24) & 0xFF], 8) & 0xFFFFFFFF
|
|
425
|
+
self.c3 ^= key[r][3] & 0xFFFFFFFF
|
|
426
|
+
r = r + 1
|
|
427
|
+
|
|
428
|
+
r0 = self.AES[self.c0 & 0xFF] & 0xFFFFFFFF
|
|
429
|
+
r0 ^= self.shift(self.AES[(self.c1 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
430
|
+
r0 ^= self.shift(self.AES[(self.c2 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
431
|
+
r0 ^= self.shift(self.AES[self.c3 >> 24], 8) & 0xFFFFFFFF
|
|
432
|
+
r0 ^= key[r][0] & 0xFFFFFFFF
|
|
433
|
+
r1 = self.AES[self.c1 & 0xFF] & 0xFFFFFFFF
|
|
434
|
+
r1 ^= self.shift(self.AES[(self.c2 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
435
|
+
r1 ^= self.shift(self.AES[(self.c3 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
436
|
+
r1 ^= self.shift(self.AES[self.c0 >> 24], 8) & 0xFFFFFFFF
|
|
437
|
+
r1 ^= key[r][1] & 0xFFFFFFFF
|
|
438
|
+
r2 = self.AES[self.c2 & 0xFF] & 0xFFFFFFFF
|
|
439
|
+
r2 ^= self.shift(self.AES[(self.c3 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
440
|
+
r2 ^= self.shift(self.AES[(self.c0 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
441
|
+
r2 ^= self.shift(self.AES[self.c1 >> 24], 8) & 0xFFFFFFFF
|
|
442
|
+
r2 ^= key[r][2] & 0xFFFFFFFF
|
|
443
|
+
r3 = self.AES[self.c3 & 0xFF] & 0xFFFFFFFF
|
|
444
|
+
r3 ^= self.shift(self.AES[(self.c0 >> 8) & 0xFF], 24) & 0xFFFFFFFF
|
|
445
|
+
r3 ^= self.shift(self.AES[(self.c1 >> 16) & 0xFF], 16) & 0xFFFFFFFF
|
|
446
|
+
r3 ^= self.shift(self.AES[self.c2 >> 24], 8) & 0xFFFFFFFF
|
|
447
|
+
r3 ^= key[r][3] & 0xFFFFFFFF
|
|
448
|
+
r += 1
|
|
449
|
+
self.c0 = (self.S_BOX[r0 & 0xFF] & 0xFF) & 0xFFFFFFFF
|
|
450
|
+
self.c0 ^= ((self.S_BOX[(r1 >> 8) & 0xFF] & 0xFF) << 8) & 0xFFFFFFFF
|
|
451
|
+
self.c0 ^= ((self.S_BOX[(r2 >> 16) & 0xFF] & 0xFF) << 16) & 0xFFFFFFFF
|
|
452
|
+
self.c0 ^= ((self.S_BOX[r3 >> 24] & 0xFF) << 24) & 0xFFFFFFFF
|
|
453
|
+
self.c0 ^= key[r][0] & 0xFFFFFFFF
|
|
454
|
+
self.c1 = (self.S_BOX[r1 & 0xFF] & 0xFF) & 0xFFFFFFFF
|
|
455
|
+
self.c1 ^= ((self.S_BOX[(r2 >> 8) & 0xFF] & 0xFF) << 8) & 0xFFFFFFFF
|
|
456
|
+
self.c1 ^= ((self.S_BOX[(r3 >> 16) & 0xFF] & 0xFF) << 16) & 0xFFFFFFFF
|
|
457
|
+
self.c1 ^= ((self.S_BOX[r0 >> 24] & 0xFF) << 24) & 0xFFFFFFFF
|
|
458
|
+
self.c1 ^= key[r][1] & 0xFFFFFFFF
|
|
459
|
+
self.c2 = (self.S_BOX[r2 & 0xFF] & 0xFF) & 0xFFFFFFFF
|
|
460
|
+
self.c2 ^= ((self.S_BOX[(r3 >> 8) & 0xFF] & 0xFF) << 8) & 0xFFFFFFFF
|
|
461
|
+
self.c2 ^= ((self.S_BOX[(r0 >> 16) & 0xFF] & 0xFF) << 16) & 0xFFFFFFFF
|
|
462
|
+
self.c2 ^= ((self.S_BOX[r1 >> 24] & 0xFF) << 24) & 0xFFFFFFFF
|
|
463
|
+
self.c2 ^= key[r][2] & 0xFFFFFFFF
|
|
464
|
+
self.c3 = (self.S_BOX[r3 & 0xFF] & 0xFF) & 0xFFFFFFFF
|
|
465
|
+
self.c3 ^= ((self.S_BOX[(r0 >> 8) & 0xFF] & 0xFF) << 8) & 0xFFFFFFFF
|
|
466
|
+
self.c3 ^= ((self.S_BOX[(r1 >> 16) & 0xFF] & 0xFF) << 16) & 0xFFFFFFFF
|
|
467
|
+
self.c3 ^= ((self.S_BOX[r2 >> 24] & 0xFF) << 24) & 0xFFFFFFFF
|
|
468
|
+
self.c3 ^= key[r][3] & 0xFFFFFFFF
|
|
469
|
+
|
|
470
|
+
def decryptBlock(self, key):
|
|
471
|
+
t0 = self.c0 ^ key[self.rounds][0]
|
|
472
|
+
t1 = self.c1 ^ key[self.rounds][1]
|
|
473
|
+
t2 = self.c2 ^ key[self.rounds][2]
|
|
474
|
+
r0 = r1 = r2 = 0
|
|
475
|
+
r3 = self.c3 ^ key[self.rounds][3]
|
|
476
|
+
r = self.rounds - 1
|
|
477
|
+
while r > 1:
|
|
478
|
+
r0 = (self.AES1_REVERSED[t0 & 255] & 0xFFFFFFFF) ^ self.shift(self.AES1_REVERSED[(r3 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t2 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t1 >> 24) & 255], 8) ^ key[r][0]
|
|
479
|
+
r1 = self.AES1_REVERSED[t1 & 255] ^ self.shift(self.AES1_REVERSED[(t0 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r3 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t2 >> 24) & 255], 8) ^ key[r][1]
|
|
480
|
+
r2 = self.AES1_REVERSED[t2 & 255] ^ self.shift(self.AES1_REVERSED[(t1 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t0 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r3 >> 24) & 255], 8) ^ key[r][2]
|
|
481
|
+
r3 = self.AES1_REVERSED[r3 & 255] ^ self.shift(self.AES1_REVERSED[(t2 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t1 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t0 >> 24) & 255], 8) ^ key[r][3]
|
|
482
|
+
r -= 1
|
|
483
|
+
t0 = self.AES1_REVERSED[r0 & 255] ^ self.shift(self.AES1_REVERSED[(r3 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r2 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r1 >> 24) & 255], 8) ^ key[r][0]
|
|
484
|
+
t1 = self.AES1_REVERSED[r1 & 255] ^ self.shift(self.AES1_REVERSED[(r0 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r3 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r2 >> 24) & 255], 8) ^ key[r][1]
|
|
485
|
+
t2 = self.AES1_REVERSED[r2 & 255] ^ self.shift(self.AES1_REVERSED[(r1 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r0 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r3 >> 24) & 255], 8) ^ key[r][2]
|
|
486
|
+
r3 = self.AES1_REVERSED[r3 & 255] ^ self.shift(self.AES1_REVERSED[(r2 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r1 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r0 >> 24) & 255], 8) ^ key[r][3]
|
|
487
|
+
r -= 1
|
|
488
|
+
r = 1
|
|
489
|
+
r0 = self.AES1_REVERSED[t0 & 255] ^ self.shift(self.AES1_REVERSED[(r3 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t2 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t1 >> 24) & 255], 8) ^ key[r][0]
|
|
490
|
+
r1 = self.AES1_REVERSED[t1 & 255] ^ self.shift(self.AES1_REVERSED[(t0 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(r3 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t2 >> 24) & 255], 8) ^ key[r][1]
|
|
491
|
+
r2 = self.AES1_REVERSED[t2 & 255] ^ self.shift(self.AES1_REVERSED[(t1 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t0 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(r3 >> 24) & 255], 8) ^ key[r][2]
|
|
492
|
+
r3 = self.AES1_REVERSED[r3 & 255] ^ self.shift(self.AES1_REVERSED[(t2 >> 8) & 255], 24) ^ self.shift(self.AES1_REVERSED[(t1 >> 16) & 255], 16) ^ self.shift(self.AES1_REVERSED[(t0 >> 24) & 255], 8) ^ key[r][3]
|
|
493
|
+
r = 0
|
|
494
|
+
self.c0 = (self.S_BOX_REVERSED[r0 & 255] & 0xFF) ^ ((((self.S_BOX_REVERSED[(r3 >> 8) & 255]) & 0xFF) << 8)) ^ ((((self.S_BOX_REVERSED[(r2 >> 16) & 255]) & 0xFF) << 16)) ^ ((((self.S_BOX_REVERSED[(r1 >> 24) & 255]) & 0xFF) << 24)) ^ key[r][0]
|
|
495
|
+
self.c1 = (self.S_BOX_REVERSED[r1 & 255] & 0xFF) ^ (((self.S_BOX_REVERSED[(r0 >> 8) & 255]) & 0xFF) << 8) ^ (((self.S_BOX_REVERSED[(r3 >> 16) & 255]) & 0xFF) << 16) ^ (((self.S_BOX_REVERSED[(r2 >> 24) & 255]) & 0xFF) << 24) ^ key[r][1]
|
|
496
|
+
self.c2 = (self.S_BOX_REVERSED[r2 & 255] & 0xFF) ^ (((self.S_BOX_REVERSED[(r1 >> 8) & 255]) & 0xFF) << 8) ^ (((self.S_BOX_REVERSED[(r0 >> 16) & 255]) & 0xFF) << 16) ^ (((self.S_BOX_REVERSED[(r3 >> 24) & 255]) & 0xFF) << 24) ^ key[r][2]
|
|
497
|
+
self.c3 = (self.S_BOX_REVERSED[r3 & 255] & 0xFF) ^ (((self.S_BOX_REVERSED[(r2 >> 8) & 255]) & 0xFF) << 8) ^ (((self.S_BOX_REVERSED[(r1 >> 16) & 255]) & 0xFF) << 16) ^ (((self.S_BOX_REVERSED[(r0 >> 24) & 255]) & 0xFF) << 24) ^ key[r][3]
|
|
498
|
+
|
|
499
|
+
def processBlock(self, input_, inOffset, forOutput, outOffset):
|
|
500
|
+
if inOffset + (32 / 2) > len(input_):
|
|
501
|
+
raise ValueError("input buffer too short")
|
|
502
|
+
if outOffset + (32 / 2) > len(forOutput):
|
|
503
|
+
raise ValueError("output buffer too short")
|
|
504
|
+
self.unPackBlock(input_, inOffset)
|
|
505
|
+
if self.encrypt:
|
|
506
|
+
self.encryptBlock(self.workingKey)
|
|
507
|
+
else:
|
|
508
|
+
self.decryptBlock(self.workingKey)
|
|
509
|
+
self.packBlock(forOutput, outOffset)
|
|
510
|
+
return self.BLOCK_SIZE
|
|
511
|
+
|
|
512
|
+
@classmethod
|
|
513
|
+
def bEToUInt32(cls, buff, offset):
|
|
514
|
+
value = (buff[offset] << 24)
|
|
515
|
+
value |= (buff[offset + 1] << 16) & 0xFF0000
|
|
516
|
+
value |= (buff[offset + 2] << 8) & 0xFF00
|
|
517
|
+
value |= buff[offset + 3] & 0xFF
|
|
518
|
+
return value
|
|
519
|
+
|
|
520
|
+
@classmethod
|
|
521
|
+
def shiftRight(cls, block, count):
|
|
522
|
+
bit = 0
|
|
523
|
+
i = 0
|
|
524
|
+
while i < 4:
|
|
525
|
+
b = block[i]
|
|
526
|
+
block[i] = (b >> count) | bit
|
|
527
|
+
bit = (b << (32 - count)) & 0xFFFFFFFF
|
|
528
|
+
i += 1
|
|
529
|
+
|
|
530
|
+
@classmethod
|
|
531
|
+
def multiplyP(cls, x):
|
|
532
|
+
lsb = (x[3] & 1) != 0
|
|
533
|
+
cls.shiftRight(x, 1)
|
|
534
|
+
if lsb:
|
|
535
|
+
x[0] ^= 0xe1000000
|
|
536
|
+
|
|
537
|
+
@classmethod
|
|
538
|
+
def getUint128(cls, buff):
|
|
539
|
+
us = [None] * 4
|
|
540
|
+
us[0] = cls.bEToUInt32(buff, 0)
|
|
541
|
+
us[1] = cls.bEToUInt32(buff, 4)
|
|
542
|
+
us[2] = cls.bEToUInt32(buff, 8)
|
|
543
|
+
us[3] = cls.bEToUInt32(buff, 12)
|
|
544
|
+
return us
|
|
545
|
+
|
|
546
|
+
@classmethod
|
|
547
|
+
def xor(cls, block, value):
|
|
548
|
+
pos = 0
|
|
549
|
+
while pos != 16:
|
|
550
|
+
block[pos] ^= value[pos]
|
|
551
|
+
pos += 1
|
|
552
|
+
|
|
553
|
+
@classmethod
|
|
554
|
+
def xor128(cls, block, value):
|
|
555
|
+
pos = 0
|
|
556
|
+
while pos != 4:
|
|
557
|
+
block[pos] ^= value[pos]
|
|
558
|
+
pos += 1
|
|
559
|
+
|
|
560
|
+
@classmethod
|
|
561
|
+
def multiplyP8(cls, x):
|
|
562
|
+
lsw = x[3]
|
|
563
|
+
cls.shiftRight(x, 8)
|
|
564
|
+
pos = 0
|
|
565
|
+
while pos != 8:
|
|
566
|
+
if (lsw & (1 << pos)) != 0:
|
|
567
|
+
x[0] ^= ((0xe1000000 >> (7 - pos)) & 0xFFFFFFFF)
|
|
568
|
+
pos += 1
|
|
569
|
+
|
|
570
|
+
def getGHash(self, b):
|
|
571
|
+
y = bytearray(16)
|
|
572
|
+
pos = 0
|
|
573
|
+
while pos < len(b):
|
|
574
|
+
x = bytearray(16)
|
|
575
|
+
cnt = min(len(b) - pos, 16)
|
|
576
|
+
x[0:cnt] = b[pos:pos + cnt]
|
|
577
|
+
self.xor(y, x)
|
|
578
|
+
self.multiplyH(y)
|
|
579
|
+
pos += 16
|
|
580
|
+
return y
|
|
581
|
+
|
|
582
|
+
@classmethod
|
|
583
|
+
def uInt32ToBE(cls, value, buff, offset):
|
|
584
|
+
buff[offset] = (value >> 24) & 0xFF
|
|
585
|
+
buff[offset + 1] = (value >> 16) & 0xFF
|
|
586
|
+
buff[offset + 2] = (value >> 8) & 0xFF
|
|
587
|
+
buff[offset + 3] = value & 0xFF
|
|
588
|
+
|
|
589
|
+
def multiplyH(self, value):
|
|
590
|
+
tmp = [0] * 4
|
|
591
|
+
pos = 0
|
|
592
|
+
while pos != 16:
|
|
593
|
+
m = self.mArray[pos + pos][value[pos] & 0x0f]
|
|
594
|
+
tmp[0] ^= m[0]
|
|
595
|
+
tmp[1] ^= m[1]
|
|
596
|
+
tmp[2] ^= m[2]
|
|
597
|
+
tmp[3] ^= m[3]
|
|
598
|
+
m = self.mArray[pos + pos + 1][(value[pos] & 0xf0) >> 4]
|
|
599
|
+
tmp[0] ^= m[0]
|
|
600
|
+
tmp[1] ^= m[1]
|
|
601
|
+
tmp[2] ^= m[2]
|
|
602
|
+
tmp[3] ^= m[3]
|
|
603
|
+
pos += 1
|
|
604
|
+
self.uInt32ToBE(tmp[0], value, 0)
|
|
605
|
+
self.uInt32ToBE(tmp[1], value, 4)
|
|
606
|
+
self.uInt32ToBE(tmp[2], value, 8)
|
|
607
|
+
self.uInt32ToBE(tmp[3], value, 12)
|
|
608
|
+
|
|
609
|
+
def init(self, value):
|
|
610
|
+
self.mArray[0] = [0] * 16
|
|
611
|
+
self.mArray[1] = [0] * 16
|
|
612
|
+
self.mArray[0][0] = [0] * 4
|
|
613
|
+
self.mArray[1][0] = [0] * 4
|
|
614
|
+
self.mArray[1][8] = self.getUint128(value)
|
|
615
|
+
tmp = []
|
|
616
|
+
pos = 4
|
|
617
|
+
while pos >= 1:
|
|
618
|
+
tmp = self.clone(self.mArray[1][pos + pos])
|
|
619
|
+
self.multiplyP(tmp)
|
|
620
|
+
self.mArray[1][pos] = tmp
|
|
621
|
+
pos >>= 1
|
|
622
|
+
tmp = self.clone(self.mArray[1][1])
|
|
623
|
+
self.multiplyP(tmp)
|
|
624
|
+
self.mArray[0][8] = tmp
|
|
625
|
+
pos = 4
|
|
626
|
+
while pos >= 1:
|
|
627
|
+
tmp = self.clone(self.mArray[0][pos + pos])
|
|
628
|
+
self.multiplyP(tmp)
|
|
629
|
+
self.mArray[0][pos] = tmp
|
|
630
|
+
pos >>= 1
|
|
631
|
+
pos1 = 0
|
|
632
|
+
while True:
|
|
633
|
+
pos2 = 2
|
|
634
|
+
while pos2 < 16:
|
|
635
|
+
k = 1
|
|
636
|
+
while k < pos2:
|
|
637
|
+
tmp = self.clone(self.mArray[pos1][pos2])
|
|
638
|
+
self.xor128(tmp, self.mArray[pos1][k])
|
|
639
|
+
self.mArray[pos1][pos2 + k] = tmp
|
|
640
|
+
k += 1
|
|
641
|
+
pos2 += pos2
|
|
642
|
+
pos1 += 1
|
|
643
|
+
if pos1 == 32:
|
|
644
|
+
return
|
|
645
|
+
if pos1 > 1:
|
|
646
|
+
self.mArray[pos1] = [0] * 16
|
|
647
|
+
self.mArray[pos1][0] = [0] * 4
|
|
648
|
+
pos = 8
|
|
649
|
+
while pos > 0:
|
|
650
|
+
tmp = self.clone(self.mArray[pos1 - 2][pos])
|
|
651
|
+
self.multiplyP8(tmp)
|
|
652
|
+
self.mArray[pos1][pos] = tmp
|
|
653
|
+
pos >>= 1
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
def gCTRBlock(self, buf, bufCount):
|
|
657
|
+
i = 15
|
|
658
|
+
while i >= 12:
|
|
659
|
+
self.counter[i] += 1
|
|
660
|
+
if self.counter[i] != 0:
|
|
661
|
+
break
|
|
662
|
+
i -= 1
|
|
663
|
+
tmp = bytearray(self.BLOCK_SIZE)
|
|
664
|
+
self.processBlock(self.counter, 0, tmp, 0)
|
|
665
|
+
if self.encrypt:
|
|
666
|
+
zeroes = bytearray(self.BLOCK_SIZE)
|
|
667
|
+
tmp[bufCount:self.BLOCK_SIZE] = zeroes[bufCount:self.BLOCK_SIZE]
|
|
668
|
+
hashBytes = tmp
|
|
669
|
+
else:
|
|
670
|
+
hashBytes = buf
|
|
671
|
+
pos = 0
|
|
672
|
+
while pos != bufCount:
|
|
673
|
+
tmp[pos] ^= buf[pos]
|
|
674
|
+
self.output.setUInt8(tmp[pos])
|
|
675
|
+
pos += 1
|
|
676
|
+
self.xor(self.s, hashBytes)
|
|
677
|
+
self.multiplyH(self.s)
|
|
678
|
+
self.totalLength += bufCount
|
|
679
|
+
|
|
680
|
+
@classmethod
|
|
681
|
+
def setPackLength(cls, length, buff, offset):
|
|
682
|
+
cls.uInt32ToBE(int((length >> 32)), buff, offset)
|
|
683
|
+
cls.uInt32ToBE(int(length), buff, offset + 4)
|
|
684
|
+
|
|
685
|
+
def reset(self):
|
|
686
|
+
self.s = self.getGHash(self.aad)
|
|
687
|
+
self.counter = self.clone(self.j0)
|
|
688
|
+
self.bytesRemaining = 0
|
|
689
|
+
self.totalLength = 0
|
|
690
|
+
|
|
691
|
+
@classmethod
|
|
692
|
+
def tagsEquals(cls, tag1, tag2):
|
|
693
|
+
pos = 0
|
|
694
|
+
while pos != 12:
|
|
695
|
+
if tag1[pos] != tag2[pos]:
|
|
696
|
+
return False
|
|
697
|
+
pos += 1
|
|
698
|
+
return True
|
|
699
|
+
|
|
700
|
+
def write(self, input_):
|
|
701
|
+
for it in input_:
|
|
702
|
+
self.bufBlock[self.bytesRemaining] = it
|
|
703
|
+
self.bytesRemaining += 1
|
|
704
|
+
if self.bytesRemaining == self.BLOCK_SIZE:
|
|
705
|
+
self.gCTRBlock(self.bufBlock, self.BLOCK_SIZE)
|
|
706
|
+
if not self.encrypt:
|
|
707
|
+
#System.arraycopy(self.bufBlock, self.BLOCK_SIZE,
|
|
708
|
+
#self.bufBlock, 0,)
|
|
709
|
+
self.bufBlock[0:len(self.tag)] = self.bufBlock[self.blockSize:self.blockSize + len(self.tag)]
|
|
710
|
+
self.bytesRemaining = 0
|
|
711
|
+
|
|
712
|
+
def flushFinalBlock(self):
|
|
713
|
+
if self.bytesRemaining > 0:
|
|
714
|
+
tmp = self.bufBlock[0:self.bytesRemaining]
|
|
715
|
+
self.gCTRBlock(tmp, self.bytesRemaining)
|
|
716
|
+
if self.security == Security.ENCRYPTION:
|
|
717
|
+
self.reset()
|
|
718
|
+
return self.output.array()
|
|
719
|
+
x = bytearray(16)
|
|
720
|
+
self.setPackLength(8 * len(self.aad), x, 0)
|
|
721
|
+
self.setPackLength(self.totalLength * 8, x, 8)
|
|
722
|
+
self.xor(self.s, x)
|
|
723
|
+
self.multiplyH(self.s)
|
|
724
|
+
generatedTag = bytearray(self.BLOCK_SIZE)
|
|
725
|
+
self.processBlock(self.j0, 0, generatedTag, 0)
|
|
726
|
+
self.xor(generatedTag, self.s)
|
|
727
|
+
if not self.encrypt:
|
|
728
|
+
if not self.tagsEquals(self.tag, generatedTag):
|
|
729
|
+
print(GXByteBuffer.hex(self.tag, False) + "-" + GXByteBuffer.hex(generatedTag, False))
|
|
730
|
+
raise ValueError("Decrypt failed. Invalid tag.")
|
|
731
|
+
else:
|
|
732
|
+
#Tag size is 12 bytes.
|
|
733
|
+
self.tag = generatedTag[0:12]
|
|
734
|
+
self.reset()
|
|
735
|
+
return self.output.array()
|
|
736
|
+
|
|
737
|
+
def generateKey(self, isEncrypt, key):
|
|
738
|
+
#Key length in words.
|
|
739
|
+
keyLen = int(len(key) / 4)
|
|
740
|
+
self.rounds = keyLen + 6
|
|
741
|
+
w = [[0 for x in range(4)] for y in range(self.rounds + 1)]
|
|
742
|
+
t = 0
|
|
743
|
+
i = 0
|
|
744
|
+
while i < len(key):
|
|
745
|
+
w[t >> 2][t & 3] = self.toUInt32(key, i)
|
|
746
|
+
i += 4
|
|
747
|
+
t += 1
|
|
748
|
+
k = (self.rounds + 1) << 2
|
|
749
|
+
i = keyLen
|
|
750
|
+
while i < k:
|
|
751
|
+
temp = w[(i - 1) >> 2][(i - 1) & 3]
|
|
752
|
+
if (i % keyLen) == 0:
|
|
753
|
+
temp = self.subWord(self.shift(temp, 8)) ^ (self.R_CON[int(i / keyLen) - 1] & 0xFF)
|
|
754
|
+
elif (keyLen > 6) and ((i % keyLen) == 4):
|
|
755
|
+
temp = self.subWord(temp)
|
|
756
|
+
w[i >> 2][i & 3] = w[(i - keyLen) >> 2][(i - keyLen) & 3] ^ temp
|
|
757
|
+
i += 1
|
|
758
|
+
if not isEncrypt:
|
|
759
|
+
j = 1
|
|
760
|
+
while j < self.rounds:
|
|
761
|
+
i = 0
|
|
762
|
+
while i < 4:
|
|
763
|
+
w[j][i] = self.imixCol(w[j][i])
|
|
764
|
+
i += 1
|
|
765
|
+
j += 1
|
|
766
|
+
return w
|
|
767
|
+
|
|
768
|
+
@classmethod
|
|
769
|
+
def galoisMultiply(cls, value):
|
|
770
|
+
if value >> 7 != 0:
|
|
771
|
+
value = value << 1
|
|
772
|
+
return (value ^ 0x1b) & 0xFF
|
|
773
|
+
|
|
774
|
+
return (value << 1) & 0xFF
|
|
775
|
+
# temp = (value >> 7) & 0xFF
|
|
776
|
+
# temp = temp & 0x1b
|
|
777
|
+
# return ((value << 1) ^ temp) & 0xFF
|
|
778
|
+
|
|
779
|
+
@classmethod
|
|
780
|
+
def aes1Encrypt(cls, data: bytearray, offset: int, secret: bytearray):
|
|
781
|
+
round_ = 0
|
|
782
|
+
i = 0
|
|
783
|
+
key = secret.copy()
|
|
784
|
+
while round_ < 10:
|
|
785
|
+
i = 0
|
|
786
|
+
while i < 16:
|
|
787
|
+
data[i + offset] = cls.S_BOX[(data[i + offset] ^ key[i]) & 0xFF]
|
|
788
|
+
i += 1
|
|
789
|
+
buf1 = data[1 + offset]
|
|
790
|
+
data[1 + offset] = data[5 + offset]
|
|
791
|
+
data[5 + offset] = data[9 + offset]
|
|
792
|
+
data[9 + offset] = data[13 + offset]
|
|
793
|
+
data[13 + offset] = buf1
|
|
794
|
+
buf1 = data[2 + offset]
|
|
795
|
+
buf2 = data[6 + offset]
|
|
796
|
+
data[2 + offset] = data[10 + offset]
|
|
797
|
+
data[6 + offset] = data[14 + offset]
|
|
798
|
+
data[10 + offset] = buf1
|
|
799
|
+
data[14 + offset] = buf2
|
|
800
|
+
buf1 = data[15 + offset]
|
|
801
|
+
data[15 + offset] = data[11 + offset]
|
|
802
|
+
data[11 + offset] = data[7 + offset]
|
|
803
|
+
data[7 + offset] = data[3 + offset]
|
|
804
|
+
data[3 + offset] = buf1
|
|
805
|
+
if round_ < 9:
|
|
806
|
+
i = 0
|
|
807
|
+
while i < 4:
|
|
808
|
+
buf4 = (i << 2) & 0xFF
|
|
809
|
+
buf1 = (data[buf4 + offset] ^ data[buf4 + 1 + offset] ^ data[buf4 + 2 + offset] ^ data[buf4 + 3 + offset]) & 0xFF
|
|
810
|
+
buf2 = data[buf4 + offset] & 0xFF
|
|
811
|
+
buf3 = (data[buf4 + offset] ^ data[buf4 + 1 + offset]) & 0xFF
|
|
812
|
+
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
813
|
+
data[buf4 + offset] = (data[buf4 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
814
|
+
buf3 = (data[buf4 + 1 + offset] ^ data[buf4 + 2 + offset]) & 0xFF
|
|
815
|
+
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
816
|
+
data[buf4 + 1 + offset] = (data[buf4 + 1 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
817
|
+
buf3 = (data[buf4 + 2 + offset] ^ data[buf4 + 3 + offset]) & 0xFF
|
|
818
|
+
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
819
|
+
data[buf4 + 2 + offset] = (data[buf4 + 2 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
820
|
+
buf3 = (data[buf4 + 3 + offset] ^ buf2) & 0xFF
|
|
821
|
+
buf3 = cls.galoisMultiply(buf3) & 0xFF
|
|
822
|
+
data[buf4 + 3 + offset] = (data[buf4 + 3 + offset] ^ buf3 ^ buf1) & 0xFF
|
|
823
|
+
i += 1
|
|
824
|
+
key[0] = (cls.S_BOX[key[13] & 0xFF] ^ key[0] ^ cls.R_CON[round_]) & 0xFF
|
|
825
|
+
key[1] = (cls.S_BOX[key[14] & 0xFF] ^ key[1]) & 0xFF
|
|
826
|
+
key[2] = (cls.S_BOX[key[15] & 0xFF] ^ key[2]) & 0xFF
|
|
827
|
+
key[3] = (cls.S_BOX[key[12] & 0xFF] ^ key[3]) & 0xFF
|
|
828
|
+
i = 4
|
|
829
|
+
while i < 16:
|
|
830
|
+
key[i] = (key[i] ^ key[i - 4]) & 0xFF
|
|
831
|
+
i += 1
|
|
832
|
+
round_ += 1
|
|
833
|
+
i = 0
|
|
834
|
+
while i < 16:
|
|
835
|
+
data[i + offset] = (data[i + offset] ^ key[i])
|
|
836
|
+
i += 1
|
|
837
|
+
|
|
838
|
+
def encryptAes(self, data):
|
|
839
|
+
n = len(data) / 8
|
|
840
|
+
if (n * 8) != len(data):
|
|
841
|
+
raise ValueError("Invalid data.")
|
|
842
|
+
iv = bytearray([0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6])
|
|
843
|
+
block = bytearray(len(data) + len(iv))
|
|
844
|
+
buf = bytearray(8 + len(iv))
|
|
845
|
+
block[0:len(self.IV)] = self.IV[0:len(self.IV)]
|
|
846
|
+
block[len(self.IV):len(self.IV) + len(data)] = data[0:len(data)]
|
|
847
|
+
j = 0
|
|
848
|
+
while j != 6:
|
|
849
|
+
i = 1
|
|
850
|
+
while i <= n:
|
|
851
|
+
buf[0:len(self.IV)] = block[0: len(self.IV)]
|
|
852
|
+
buf[len(self.IV):8 + len(self.IV)] = block[8 * i:8 * i + 8]
|
|
853
|
+
self.processBlock(buf, 0, buf, 0)
|
|
854
|
+
t = int(n * j + i)
|
|
855
|
+
k = 1
|
|
856
|
+
while t != 0:
|
|
857
|
+
v = int(t)
|
|
858
|
+
buf[len(self.IV) - k] ^= v
|
|
859
|
+
t = int(t >> 8)
|
|
860
|
+
k += 1
|
|
861
|
+
block[0:8] = buf[0:8]
|
|
862
|
+
block[8 * i:8 * i + 8] = buf[8:16]
|
|
863
|
+
i += 1
|
|
864
|
+
j += 1
|
|
865
|
+
return block
|
|
866
|
+
|
|
867
|
+
def decryptAes(self, input_):
|
|
868
|
+
n = len(input_) / 8
|
|
869
|
+
if (n * 8) != len(input_):
|
|
870
|
+
raise ValueError("Invalid data.")
|
|
871
|
+
iv = bytearray([0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6])
|
|
872
|
+
if len(input_) > len(iv):
|
|
873
|
+
block = bytearray(len(input_) - len(iv))
|
|
874
|
+
else:
|
|
875
|
+
block = bytearray(len(iv))
|
|
876
|
+
a = bytearray(len(iv))
|
|
877
|
+
buf = bytearray(8 + len(iv))
|
|
878
|
+
a[0:] = input_[0:len(iv)]
|
|
879
|
+
block[0:] = input_[len(iv):len(input_)]
|
|
880
|
+
n = n - 1
|
|
881
|
+
if n == 0:
|
|
882
|
+
n = 1
|
|
883
|
+
j = 5
|
|
884
|
+
while j >= 0:
|
|
885
|
+
i = n
|
|
886
|
+
while i >= 1:
|
|
887
|
+
buf[0:len(iv)] = a[0:len(iv)]
|
|
888
|
+
buf[len(iv):8 + len(iv)] = block[8 * int(i - 1):8 * int(i)]
|
|
889
|
+
t = n * j + i
|
|
890
|
+
k = 1
|
|
891
|
+
while t != 0:
|
|
892
|
+
v = int(t)
|
|
893
|
+
buf[len(self.IV)] ^= v
|
|
894
|
+
t = int((int(t) >> 8))
|
|
895
|
+
k += 1
|
|
896
|
+
self.processBlock(buf, 0, buf, 0)
|
|
897
|
+
a[0:] = buf[0:8]
|
|
898
|
+
block[8:16] = buf[8 * (i - 1):8*i]
|
|
899
|
+
i -= 1
|
|
900
|
+
j -= 1
|
|
901
|
+
if a != self.IV:
|
|
902
|
+
raise ValueError("Invalid data")
|
|
903
|
+
return block
|
|
904
|
+
|
|
905
|
+
@classmethod
|
|
906
|
+
def aes1Decrypt(cls, data, secret):
|
|
907
|
+
buf1 = 0
|
|
908
|
+
buf2 = 0
|
|
909
|
+
buf3 = 0
|
|
910
|
+
round_ = 0
|
|
911
|
+
i = 0
|
|
912
|
+
buf4 = 0
|
|
913
|
+
key = secret[0:]
|
|
914
|
+
while round_ < 10:
|
|
915
|
+
key[0] = int((cls.S_BOX[key[13] & 0xFF] ^ key[0] ^ cls.R_CON[round_]))
|
|
916
|
+
key[1] = int((cls.S_BOX[key[14] & 0xFF] ^ key[1]))
|
|
917
|
+
key[2] = int((cls.S_BOX[key[15] & 0xFF] ^ key[2]))
|
|
918
|
+
key[3] = int((cls.S_BOX[key[12] & 0xFF] ^ key[3]))
|
|
919
|
+
while i < 16:
|
|
920
|
+
key[i] = int((key[i] ^ key[i - 4]))
|
|
921
|
+
i += 1
|
|
922
|
+
round_ += 1
|
|
923
|
+
while i < 16:
|
|
924
|
+
data[i] = int((data[i] ^ key[i]))
|
|
925
|
+
i += 1
|
|
926
|
+
while round_ < 10:
|
|
927
|
+
while i > 3:
|
|
928
|
+
key[i] = int((key[i] ^ key[i - 4]))
|
|
929
|
+
i -= 1
|
|
930
|
+
key[0] = int((cls.S_BOX[key[13] & 0xFF] ^ key[0] ^ cls.R_CON[9 - round_]))
|
|
931
|
+
key[1] = int((cls.S_BOX[key[14] & 0xFF] ^ key[1]))
|
|
932
|
+
key[2] = int((cls.S_BOX[key[15] & 0xFF] ^ key[2]))
|
|
933
|
+
key[3] = int((cls.S_BOX[key[12] & 0xFF] ^ key[3]))
|
|
934
|
+
if round_ > 0:
|
|
935
|
+
while i < 4:
|
|
936
|
+
buf4 = (i << 2) & 0xFF
|
|
937
|
+
buf1 = cls.galoisMultiply(cls.galoisMultiply(data[buf4] ^ data[buf4 + 2]))
|
|
938
|
+
buf2 = cls.galoisMultiply(cls.galoisMultiply(data[buf4 + 1] ^ data[buf4 + 3]))
|
|
939
|
+
data[buf4] ^= buf1
|
|
940
|
+
data[buf4 + 1] ^= buf2
|
|
941
|
+
data[buf4 + 2] ^= buf1
|
|
942
|
+
data[buf4 + 3] ^= buf2
|
|
943
|
+
buf1 = int((data[buf4] ^ data[buf4 + 1] ^ data[buf4 + 2] ^ data[buf4 + 3]))
|
|
944
|
+
buf2 = data[buf4]
|
|
945
|
+
buf3 = int((data[buf4] ^ data[buf4 + 1]))
|
|
946
|
+
buf3 = cls.galoisMultiply(buf3)
|
|
947
|
+
data[buf4] = int((data[buf4] ^ buf3 ^ buf1))
|
|
948
|
+
buf3 = int((data[buf4 + 1] ^ data[buf4 + 2]))
|
|
949
|
+
buf3 = cls.galoisMultiply(buf3)
|
|
950
|
+
data[buf4 + 1] = int((data[buf4 + 1] ^ buf3 ^ buf1))
|
|
951
|
+
buf3 = int((data[buf4 + 2] ^ data[buf4 + 3]))
|
|
952
|
+
buf3 = cls.galoisMultiply(buf3)
|
|
953
|
+
data[buf4 + 2] = int((data[buf4 + 2] ^ buf3 ^ buf1))
|
|
954
|
+
buf3 = int((data[buf4 + 3] ^ buf2))
|
|
955
|
+
buf3 = cls.galoisMultiply(buf3)
|
|
956
|
+
data[buf4 + 3] = int((data[buf4 + 3] ^ buf3 ^ buf1))
|
|
957
|
+
i += 1
|
|
958
|
+
buf1 = data[13]
|
|
959
|
+
data[13] = data[9]
|
|
960
|
+
data[9] = data[5]
|
|
961
|
+
data[5] = data[1]
|
|
962
|
+
data[1] = buf1
|
|
963
|
+
buf1 = data[10]
|
|
964
|
+
buf2 = data[14]
|
|
965
|
+
data[10] = data[2]
|
|
966
|
+
data[14] = data[6]
|
|
967
|
+
data[2] = buf1
|
|
968
|
+
data[6] = buf2
|
|
969
|
+
buf1 = data[3]
|
|
970
|
+
data[3] = data[7]
|
|
971
|
+
data[7] = data[11]
|
|
972
|
+
data[11] = data[15]
|
|
973
|
+
data[15] = buf1
|
|
974
|
+
while i < 16:
|
|
975
|
+
data[i] = int((cls.S_BOX_REVERSED[data[i] & 0xFF] ^ key[i]))
|
|
976
|
+
i += 1
|
|
977
|
+
round_ += 1
|