1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Crypto Component */
16 /** */
17 /** AES Encryption */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22
23 /* Include necessary system files. */
24
25 #include "nx_crypto_aes.h"
26 #include "nx_crypto_xcbc_mac.h"
27
28 #if !defined(NX_CRYPTO_LITTLE_ENDIAN)
29 /*
30 Encryption table for BIG ENDIAN architecture.
31
32 Lookup table for computing the MixColumns() Transformation with SubBytes applied to input value S.
33 Each entry of this table represents the result of {02} dot S[x,c] | {01} dot S[x,c] | {01} dot S[x,c] | {03} dot S[x,c]. See Equation
34 5.6 on page 18 AES specification(Pub 197)
35
36 The most significant byte is the result of {02} dot S, and the least significant byte is the result
37 of {03} dot S[x,c].
38 */
39 NX_CRYPTO_AES_TABLE ULONG aes_encryption_table[256] =
40 {
41 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
42 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
43 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
44 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
45 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
46 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
47 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
48 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
49 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
50 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
51 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
52 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
53 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
54 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
55 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
56 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
57 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
58 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
59 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
60 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
61 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
62 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
63 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
64 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
65 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
66 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
67 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
68 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
69 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
70 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
71 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
72 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
73 };
74
75
76 /*
77 Decryption table for LITTLE ENDIAN architecture.
78
79 Lookup table for computing the InvMixColumns() Transformation with InvSubBytes applied to input
80 value S. Each entry of this table represents
81 the result of {0e} dot S[x,c] | {09} dot S[x,c] | {0d} dot S[x,c] | {0b} dot S[x,c]. See Equation
82 5.10 on page 23 AES specification(Pub 197)
83
84 The most significant byte is the result of {0e} dot S, and the least significant byte is the result
85 of {0b} dot S[x,c].
86 */
87 NX_CRYPTO_AES_TABLE ULONG aes_decryption_table[256] =
88 {
89 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
90 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
91 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
92 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
93 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
94 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
95 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
96 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
97 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
98 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
99 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
100 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
101 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
102 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
103 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
104 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
105 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
106 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
107 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
108 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
109 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
110 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
111 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
112 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
113 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
114 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
115 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
116 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
117 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
118 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
119 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
120 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
121 };
122
123 /*
124 Inverse Mix Table for LITTLE ENDIAN architecture.
125 Lookup table for computing the InvMixColumns() Transformation. Each entry of this table represents
126 the result of {0e} dot S[x,c] | {09} dot S[x,c] | {0d} dot S[x,c] | {0b} dot S[x,c]. See Equation
127 5.10 on page 23 AES specification(Pub 197)
128
129 The most significant byte is the result of {0e} dot S, and the least significant byte is the result
130 of {0b} dot S[x,c].
131 */
132 NX_CRYPTO_AES_TABLE ULONG aes_inv_mix_table[256] =
133 {
134 0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927, 0x24362e3a, 0x2a3f2331,
135 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45, 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69,
136 0xe090d0b0, 0xee99ddbb, 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381,
137 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf, 0xb4ee96d2, 0xbae79bd9,
138 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66, 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a,
139 0xab73d323, 0xa57ade28, 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012,
140 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec, 0x1f9d45f1, 0x119448fa,
141 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e, 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2,
142 0xad766df6, 0xa37f60fd, 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7,
143 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89, 0xf9082b94, 0xf701269f,
144 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b, 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77,
145 0x3daed51e, 0x33a7d815, 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f,
146 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa, 0x527bf8b7, 0x5c72f5bc,
147 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8, 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4,
148 0x96dd063d, 0x98d40b36, 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c,
149 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742, 0xc2a3405f, 0xccaa4d54,
150 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea, 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6,
151 0x31a4b2af, 0x3fadbfa4, 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e,
152 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360, 0x854a247d, 0x8b432976,
153 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502, 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e,
154 0x9ad7618c, 0x94de6c87, 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd,
155 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3, 0xcea927ee, 0xc0a02ae5,
156 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621, 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d,
157 0x0a0fd964, 0x0406d46f, 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55,
158 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26, 0xc8ac993b, 0xc6a59430,
159 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844, 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68,
160 0x0c0a67b1, 0x02036aba, 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480,
161 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce, 0x587421d3, 0x567d2cd8,
162 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67, 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b,
163 0x47e96422, 0x49e06929, 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713,
164 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed, 0xf307f2f0, 0xfd0efffb,
165 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f, 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3
166 };
167
168 #else
169
170 /*
171 Encryption table for LITTLE ENDIAN architecture.
172
173 Lookup table for computing the MixColumns() Transformation with SubBytes applied to input value S.
174 Each entry of this table represents the result of {02} dot S[x,c] | {01} dot S[x,c] | {01} dot S[x,c] | {03} dot S[x,c]. See Equation
175 5.6 on page 18 AES specification(Pub 197)
176
177 The most significant byte is the result of {02} dot S, and the least significant byte is the result
178 of {03} dot S[x,c].
179 */
180
181 NX_CRYPTO_AES_TABLE ULONG aes_encryption_table[256] =
182 {
183 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
184 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
185 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
186 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
187 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
188 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
189 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
190 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
191 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
192 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
193 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
194 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
195 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
196 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
197 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
198 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
199 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
200 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
201 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
202 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
203 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
204 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
205 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
206 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
207 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
208 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
209 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
210 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
211 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
212 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
213 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
214 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
215 };
216
217 /*
218 Decryption table for LITTLE ENDIAN architecture.
219
220 Lookup table for computing the InvMixColumns() Transformation with InvSubBytes applied to input
221 value S. Each entry of this table represents
222 the result of {0e} dot S[x,c] | {09} dot S[x,c] | {0d} dot S[x,c] | {0b} dot S[x,c]. See Equation
223 5.10 on page 23 AES specification(Pub 197)
224
225 The most significant byte is the result of {0e} dot S, and the least significant byte is the result
226 of {0b} dot S[x,c].
227 */
228 NX_CRYPTO_AES_TABLE ULONG aes_decryption_table[256] =
229 {
230 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
231 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5,
232 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
233 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,
234 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
235 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
236 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566,
237 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed,
238 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
239 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
240 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060,
241 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
242 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c,
243 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,
244 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
245 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14,
246 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b,
247 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
248 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,
249 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
250 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
251 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382,
252 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb,
253 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,
254 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
255 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117,
256 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
257 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d,
258 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,
259 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
260 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff,
261 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0
262 };
263
264 /*
265 Inverse Mix Table for LITTLE ENDIAN architecture.
266 Lookup table for computing the InvMixColumns() Transformation. Each entry of this table represents
267 the result of {0e} dot S[x,c] | {09} dot S[x,c] | {0d} dot S[x,c] | {0b} dot S[x,c]. See Equation
268 5.10 on page 23 AES specification(Pub 197)
269
270 The most significant byte is the result of {0e} dot S, and the least significant byte is the result
271 of {0b} dot S[x,c].
272 */
273
274 NX_CRYPTO_AES_TABLE ULONG aes_inv_mix_table[256] =
275 {
276 0x00000000, 0x0b0d090e, 0x161a121c, 0x1d171b12, 0x2c342438, 0x27392d36, 0x3a2e3624, 0x31233f2a,
277 0x58684870, 0x5365417e, 0x4e725a6c, 0x457f5362, 0x745c6c48, 0x7f516546, 0x62467e54, 0x694b775a,
278 0xb0d090e0, 0xbbdd99ee, 0xa6ca82fc, 0xadc78bf2, 0x9ce4b4d8, 0x97e9bdd6, 0x8afea6c4, 0x81f3afca,
279 0xe8b8d890, 0xe3b5d19e, 0xfea2ca8c, 0xf5afc382, 0xc48cfca8, 0xcf81f5a6, 0xd296eeb4, 0xd99be7ba,
280 0x7bbb3bdb, 0x70b632d5, 0x6da129c7, 0x66ac20c9, 0x578f1fe3, 0x5c8216ed, 0x41950dff, 0x4a9804f1,
281 0x23d373ab, 0x28de7aa5, 0x35c961b7, 0x3ec468b9, 0x0fe75793, 0x04ea5e9d, 0x19fd458f, 0x12f04c81,
282 0xcb6bab3b, 0xc066a235, 0xdd71b927, 0xd67cb029, 0xe75f8f03, 0xec52860d, 0xf1459d1f, 0xfa489411,
283 0x9303e34b, 0x980eea45, 0x8519f157, 0x8e14f859, 0xbf37c773, 0xb43ace7d, 0xa92dd56f, 0xa220dc61,
284 0xf66d76ad, 0xfd607fa3, 0xe07764b1, 0xeb7a6dbf, 0xda595295, 0xd1545b9b, 0xcc434089, 0xc74e4987,
285 0xae053edd, 0xa50837d3, 0xb81f2cc1, 0xb31225cf, 0x82311ae5, 0x893c13eb, 0x942b08f9, 0x9f2601f7,
286 0x46bde64d, 0x4db0ef43, 0x50a7f451, 0x5baafd5f, 0x6a89c275, 0x6184cb7b, 0x7c93d069, 0x779ed967,
287 0x1ed5ae3d, 0x15d8a733, 0x08cfbc21, 0x03c2b52f, 0x32e18a05, 0x39ec830b, 0x24fb9819, 0x2ff69117,
288 0x8dd64d76, 0x86db4478, 0x9bcc5f6a, 0x90c15664, 0xa1e2694e, 0xaaef6040, 0xb7f87b52, 0xbcf5725c,
289 0xd5be0506, 0xdeb30c08, 0xc3a4171a, 0xc8a91e14, 0xf98a213e, 0xf2872830, 0xef903322, 0xe49d3a2c,
290 0x3d06dd96, 0x360bd498, 0x2b1ccf8a, 0x2011c684, 0x1132f9ae, 0x1a3ff0a0, 0x0728ebb2, 0x0c25e2bc,
291 0x656e95e6, 0x6e639ce8, 0x737487fa, 0x78798ef4, 0x495ab1de, 0x4257b8d0, 0x5f40a3c2, 0x544daacc,
292 0xf7daec41, 0xfcd7e54f, 0xe1c0fe5d, 0xeacdf753, 0xdbeec879, 0xd0e3c177, 0xcdf4da65, 0xc6f9d36b,
293 0xafb2a431, 0xa4bfad3f, 0xb9a8b62d, 0xb2a5bf23, 0x83868009, 0x888b8907, 0x959c9215, 0x9e919b1b,
294 0x470a7ca1, 0x4c0775af, 0x51106ebd, 0x5a1d67b3, 0x6b3e5899, 0x60335197, 0x7d244a85, 0x7629438b,
295 0x1f6234d1, 0x146f3ddf, 0x097826cd, 0x02752fc3, 0x335610e9, 0x385b19e7, 0x254c02f5, 0x2e410bfb,
296 0x8c61d79a, 0x876cde94, 0x9a7bc586, 0x9176cc88, 0xa055f3a2, 0xab58faac, 0xb64fe1be, 0xbd42e8b0,
297 0xd4099fea, 0xdf0496e4, 0xc2138df6, 0xc91e84f8, 0xf83dbbd2, 0xf330b2dc, 0xee27a9ce, 0xe52aa0c0,
298 0x3cb1477a, 0x37bc4e74, 0x2aab5566, 0x21a65c68, 0x10856342, 0x1b886a4c, 0x069f715e, 0x0d927850,
299 0x64d90f0a, 0x6fd40604, 0x72c31d16, 0x79ce1418, 0x48ed2b32, 0x43e0223c, 0x5ef7392e, 0x55fa3020,
300 0x01b79aec, 0x0aba93e2, 0x17ad88f0, 0x1ca081fe, 0x2d83bed4, 0x268eb7da, 0x3b99acc8, 0x3094a5c6,
301 0x59dfd29c, 0x52d2db92, 0x4fc5c080, 0x44c8c98e, 0x75ebf6a4, 0x7ee6ffaa, 0x63f1e4b8, 0x68fcedb6,
302 0xb1670a0c, 0xba6a0302, 0xa77d1810, 0xac70111e, 0x9d532e34, 0x965e273a, 0x8b493c28, 0x80443526,
303 0xe90f427c, 0xe2024b72, 0xff155060, 0xf418596e, 0xc53b6644, 0xce366f4a, 0xd3217458, 0xd82c7d56,
304 0x7a0ca137, 0x7101a839, 0x6c16b32b, 0x671bba25, 0x5638850f, 0x5d358c01, 0x40229713, 0x4b2f9e1d,
305 0x2264e947, 0x2969e049, 0x347efb5b, 0x3f73f255, 0x0e50cd7f, 0x055dc471, 0x184adf63, 0x1347d66d,
306 0xcadc31d7, 0xc1d138d9, 0xdcc623cb, 0xd7cb2ac5, 0xe6e815ef, 0xede51ce1, 0xf0f207f3, 0xfbff0efd,
307 0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5, 0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d
308 };
309
310
311 #endif
312
313 /* S-Box. Refer to figure 7 on page 16, AES specification(Pub 197) */
314 NX_CRYPTO_AES_TABLE UCHAR sub_bytes_sbox[] =
315 {
316 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
317 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
318 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
319 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
320 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
321 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
322 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
323 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
324 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
325 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
326 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
327 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
328 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
329 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
330 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
331 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
332 };
333
334 /* Inverse S-Box. Refer to figure 14 on page 22, AES specification(Pub 197) */
335 NX_CRYPTO_AES_TABLE UCHAR inverse_sub_bytes_sbox[] =
336 {
337 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
338 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
339 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
340 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
341 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
342 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
343 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
344 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
345 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
346 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
347 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
348 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
349 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
350 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
351 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
352 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
353 };
354
355
356 /* Rcon array, used for key expansion. Refer to Appendix A on page 27, AES specification(Pub 197) */
357 NX_CRYPTO_AES_TABLE UCHAR aes_rcon_array[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
358
359 /* This array is generated using the nx_crypto_aes_multiply function, as powers of x in the
360 AES polynomial field. The array is shifted such that the indexes line up so that x**1 is
361 at index 1. The powers of x are cyclical, so the element at index 0 is actually x**255. */
362 /* For Little endian */
363 #ifdef NX_CRYPTO_LITTLE_ENDIAN
364 #define LEFT_ROTATE8(val) (((val) >> 8) | ((val) << 24))
365 #define LEFT_ROTATE16(val) (((val) >> 16) | ((val) << 16))
366 #define LEFT_ROTATE24(val) (((val) >> 24) | ((val) << 8))
367 #define SET_MSB_BYTE(val) ((UINT)(val))
368 #define SET_2ND_BYTE(val) ((UINT)(val) << 8)
369 #define SET_3RD_BYTE(val) ((UINT)(val) << 16)
370 #define SET_LSB_BYTE(val) ((UINT)(val) << 24)
371 #define EXTRACT_MSB_BYTE(val) ((val) & 0xFF)
372 #define EXTRACT_2ND_BYTE(val) (((val) >> 8) & 0xFF)
373 #define EXTRACT_3RD_BYTE(val) (((val) >> 16) & 0xFF)
374 #define EXTRACT_LSB_BYTE(val) ((val) >> 24)
375
376 #define SWAP_ENDIAN(val) ((((val) & 0xFF000000) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24))
377
378
379
380 /* End of for little endian */
381 /* For Big Endian */
382 #else
383 #define LEFT_ROTATE8(val) (((val) << 8) | ((val) >> 24))
384 #define LEFT_ROTATE16(val) (((val) >> 16) | ((val) << 16))
385 #define LEFT_ROTATE24(val) (((val) << 24) | ((val) >> 8))
386
387 #define SET_MSB_BYTE(val) ((val) << 24)
388 #define SET_2ND_BYTE(val) ((val) << 16)
389 #define SET_3RD_BYTE(val) ((val) << 8)
390 #define SET_LSB_BYTE(val) ((UINT)(val))
391 #define EXTRACT_MSB_BYTE(val) ((val) >> 24)
392 #define EXTRACT_2ND_BYTE(val) (((val) >> 16) & 0xFF)
393 #define EXTRACT_3RD_BYTE(val) (((val) >> 8) & 0xFF)
394 #define EXTRACT_LSB_BYTE(val) ((val) & 0xFF)
395
396 #endif
397
398 #ifdef NX_CRYPTO_SELF_TEST
399 extern UINT _nx_crypto_library_state;
400 #endif /* NX_CRYPTO_SELF_TEST */
401
402 /**************************************************************************/
403 /* Utility routines */
404 /**************************************************************************/
405
406
407
408 /**************************************************************************/
409 /* */
410 /* FUNCTION RELEASE */
411 /* */
412 /* _nx_crypto_aes_add_round_key PORTABLE C */
413 /* 6.1.7 */
414 /* AUTHOR */
415 /* */
416 /* Timothy Stapko, Microsoft Corporation */
417 /* */
418 /* DESCRIPTION */
419 /* */
420 /* This function implements AddRoundKey() function described in */
421 /* section 5.1.4 of the AES specification(Pub 197) */
422 /* */
423 /* INPUT */
424 /* */
425 /* aes_ptr Pointer to AES control block */
426 /* round_key Pointer to key schedule */
427 /* */
428 /* OUTPUT */
429 /* */
430 /* None */
431 /* */
432 /* CALLS */
433 /* */
434 /* None */
435 /* */
436 /* CALLED BY */
437 /* */
438 /* _nx_crypto_aes_encrypt Perform AES mode encryption */
439 /* _nx_crypto_aes_decrypt Perform AES mode decryption */
440 /* */
441 /* RELEASE HISTORY */
442 /* */
443 /* DATE NAME DESCRIPTION */
444 /* */
445 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
446 /* 09-30-2020 Timothy Stapko Modified comment(s), updated */
447 /* constants and conditionals, */
448 /* resulting in version 6.1 */
449 /* 06-02-2021 Bhupendra Naphade Modified comment(s), */
450 /* renamed FIPS symbol to */
451 /* self-test, */
452 /* resulting in version 6.1.7 */
453 /* */
454 /**************************************************************************/
_nx_crypto_aes_add_round_key(NX_CRYPTO_AES * aes_ptr,UINT * round_key)455 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_add_round_key(NX_CRYPTO_AES *aes_ptr, UINT *round_key)
456 {
457 UINT i;
458
459 for (i = 0; i < 4; ++i)
460 {
461 aes_ptr -> nx_crypto_aes_state[i] ^= round_key[i];
462 }
463 }
464
465
466 /**************************************************************************/
467 /* Encryption routines */
468 /**************************************************************************/
469 /**************************************************************************/
470 /* */
471 /* FUNCTION RELEASE */
472 /* */
473 /* _nx_crypto_aes_sub_shift_roundkey PORTABLE C */
474 /* 6.1 */
475 /* AUTHOR */
476 /* */
477 /* Timothy Stapko, Microsoft Corporation */
478 /* */
479 /* DESCRIPTION */
480 /* */
481 /* This function combines the following operations: */
482 /* SubBytes(state) */
483 /* Shiftrows(state) */
484 /* AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1]) */
485 /* Refer to Figure 5 on page 15 of the AES Specification (Pub 197) */
486 /* */
487 /* INPUT */
488 /* */
489 /* aes_ptr Pointer to AES control block */
490 /* round_key Pointer to round key */
491 /* */
492 /* OUTPUT */
493 /* */
494 /* None */
495 /* */
496 /* CALLS */
497 /* */
498 /* None */
499 /* */
500 /* CALLED BY */
501 /* */
502 /* _nx_crypto_aes_encrypt Perform AES mode encryption */
503 /* */
504 /* RELEASE HISTORY */
505 /* */
506 /* DATE NAME DESCRIPTION */
507 /* */
508 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
509 /* 09-30-2020 Timothy Stapko Modified comment(s), */
510 /* resulting in version 6.1 */
511 /* */
512 /**************************************************************************/
_nx_crypto_aes_sub_shift_roundkey(NX_CRYPTO_AES * aes_ptr,UINT * round_key)513 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_sub_shift_roundkey(NX_CRYPTO_AES *aes_ptr, UINT *round_key)
514 {
515 /*
516 S00 S04 S08 S12 S00 S04 S08 S12
517
518 S01 S05 S09 S13 S05 S09 S13 S01
519 --->
520 S02 S06 S10 S14 S10 S14 S02 S06
521
522 S03 S07 S11 S15 S15 S03 S07 S11
523 */
524
525
526 UINT S0, S1, S2, S3;
527 UCHAR *S;
528
529 S = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
530
531 S0 = ((SET_MSB_BYTE(sub_bytes_sbox[S[0]])) |
532 (SET_2ND_BYTE(sub_bytes_sbox[S[5]])) |
533 (SET_3RD_BYTE(sub_bytes_sbox[S[10]])) |
534 (SET_LSB_BYTE(sub_bytes_sbox[S[15]]))) ^ round_key[0];
535
536 S1 = ((SET_MSB_BYTE(sub_bytes_sbox[S[4]])) |
537 (SET_2ND_BYTE(sub_bytes_sbox[S[9]])) |
538 (SET_3RD_BYTE(sub_bytes_sbox[S[14]])) |
539 (SET_LSB_BYTE(sub_bytes_sbox[S[03]]))) ^ round_key[1];
540
541 S2 = ((SET_MSB_BYTE(sub_bytes_sbox[S[8]])) |
542 (SET_2ND_BYTE(sub_bytes_sbox[S[13]])) |
543 (SET_3RD_BYTE(sub_bytes_sbox[S[02]])) |
544 (SET_LSB_BYTE(sub_bytes_sbox[S[07]]))) ^ round_key[2];
545
546 S3 = ((SET_MSB_BYTE(sub_bytes_sbox[S[12]])) |
547 (SET_2ND_BYTE(sub_bytes_sbox[S[1]])) |
548 (SET_3RD_BYTE(sub_bytes_sbox[S[06]])) |
549 (SET_LSB_BYTE(sub_bytes_sbox[S[11]]))) ^ round_key[3];
550
551 aes_ptr -> nx_crypto_aes_state[0] = S0;
552 aes_ptr -> nx_crypto_aes_state[1] = S1;
553 aes_ptr -> nx_crypto_aes_state[2] = S2;
554 aes_ptr -> nx_crypto_aes_state[3] = S3;
555
556 #ifdef NX_SECURE_KEY_CLEAR
557 S0 = 0; S1 = 0; S2 = 0; S3 = 0;
558 #endif /* NX_SECURE_KEY_CLEAR */
559 }
560
561 /**************************************************************************/
562 /* */
563 /* FUNCTION RELEASE */
564 /* */
565 /* _nx_crypto_aes_inv_sub_shift_roundkey PORTABLE C */
566 /* 6.1 */
567 /* AUTHOR */
568 /* */
569 /* Timothy Stapko, Microsoft Corporation */
570 /* */
571 /* DESCRIPTION */
572 /* */
573 /* This function combines the following operations in EqInvCipher: */
574 /* InvSubBytes(state) */
575 /* InvShiftrows(state) */
576 /* AddRoundKey(state, dw[0, Nb-1]) */
577 /* Refer to Figure 15 on page 25 of the AES Specification (Pub 197) */
578 /* */
579 /* INPUT */
580 /* */
581 /* aes_ptr Pointer to AES control block */
582 /* round_key Pointer to round key */
583 /* */
584 /* OUTPUT */
585 /* */
586 /* None */
587 /* */
588 /* CALLS */
589 /* */
590 /* None */
591 /* */
592 /* CALLED BY */
593 /* */
594 /* _nx_crypto_aes_decrypt Perform AES mode decryption */
595 /* */
596 /* RELEASE HISTORY */
597 /* */
598 /* DATE NAME DESCRIPTION */
599 /* */
600 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
601 /* 09-30-2020 Timothy Stapko Modified comment(s), */
602 /* resulting in version 6.1 */
603 /* */
604 /**************************************************************************/
_nx_crypto_aes_inv_sub_shift_roundkey(NX_CRYPTO_AES * aes_ptr,UINT * round_key)605 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_inv_sub_shift_roundkey(NX_CRYPTO_AES *aes_ptr, UINT *round_key)
606 {
607 /*
608 S00 S04 S08 S12 S00 S04 S08 S12
609
610 S01 S05 S09 S13 S13 S01 S05 S09
611 --->
612 S02 S06 S10 S14 S10 S14 S02 S06
613
614 S03 S07 S11 S15 S07 S11 S15 S03
615 */
616
617
618 UINT S0, S1, S2, S3;
619 UCHAR *S;
620
621 S = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
622
623 S0 = ((SET_MSB_BYTE(inverse_sub_bytes_sbox[S[0]])) |
624 (SET_2ND_BYTE(inverse_sub_bytes_sbox[S[13]])) |
625 (SET_3RD_BYTE(inverse_sub_bytes_sbox[S[10]])) |
626 (SET_LSB_BYTE(inverse_sub_bytes_sbox[S[7]]))) ^ round_key[0];
627
628 S1 = ((SET_MSB_BYTE(inverse_sub_bytes_sbox[S[4]])) |
629 (SET_2ND_BYTE(inverse_sub_bytes_sbox[S[1]])) |
630 (SET_3RD_BYTE(inverse_sub_bytes_sbox[S[14]])) |
631 (SET_LSB_BYTE(inverse_sub_bytes_sbox[S[11]]))) ^ round_key[1];
632
633 S2 = ((SET_MSB_BYTE(inverse_sub_bytes_sbox[S[8]])) |
634 (SET_2ND_BYTE(inverse_sub_bytes_sbox[S[5]])) |
635 (SET_3RD_BYTE(inverse_sub_bytes_sbox[S[2]])) |
636 (SET_LSB_BYTE(inverse_sub_bytes_sbox[S[15]]))) ^ round_key[2];
637
638 S3 = ((SET_MSB_BYTE(inverse_sub_bytes_sbox[S[12]])) |
639 (SET_2ND_BYTE(inverse_sub_bytes_sbox[S[9]])) |
640 (SET_3RD_BYTE(inverse_sub_bytes_sbox[S[6]])) |
641 (SET_LSB_BYTE(inverse_sub_bytes_sbox[S[3]]))) ^ round_key[3];
642
643
644 aes_ptr -> nx_crypto_aes_state[0] = S0;
645 aes_ptr -> nx_crypto_aes_state[1] = S1;
646 aes_ptr -> nx_crypto_aes_state[2] = S2;
647 aes_ptr -> nx_crypto_aes_state[3] = S3;
648
649 #ifdef NX_SECURE_KEY_CLEAR
650 S0= 0; S1 = 0; S2 = 0; S3 = 0;
651 #endif /* NX_SECURE_KEY_CLEAR */
652 }
653
654
655 /*
656
657 __ __ __ __ __ __
658 | S0'| | 02 03 01 01| | S0 |
659 | S1'| | 01 02 03 01| | S1 |
660 | S2'| = | 01 01 02 03| | S2 |
661 | S3'| | 03 01 01 02| | S3 |
662 -- -- -- -- -- --
663
664 S' = V0 ^ V1 ^ V2 ^ V3
665 S0' = {02}*S0 ^ {03}*S1 ^ {01}*S2 ^ {01}*S3
666 S1' = {01}*S0 ^ {02}*S1 ^ {03}*S2 ^ {01}*S3
667 S2' = {01}*S0 ^ {01}*S1 ^ {02}*S2 ^ {03}*S3
668 S3' = {03}*S0 ^ {01}*S1 ^ {01}*S2 ^ {02}*S3
669
670
671 */
672
673
674 /**************************************************************************/
675 /* */
676 /* FUNCTION RELEASE */
677 /* */
678 /* _nx_crypto_aes_encryption_round PORTABLE C */
679 /* 6.1 */
680 /* AUTHOR */
681 /* */
682 /* Timothy Stapko, Microsoft Corporation */
683 /* */
684 /* DESCRIPTION */
685 /* */
686 /* This function combines the following operations: */
687 /* SubBytes(state) */
688 /* Shiftrows(state) */
689 /* MixColumns(state) */
690 /* AddRoundKey(state, w[round*Nb, (round+1)*Nb-1]) */
691 /* This step is the body of the loop in the middle of Cipher. */
692 /* Refer to Figure 5 on page 15 of the AES Specification (Pub 197) */
693 /* */
694 /* INPUT */
695 /* */
696 /* aes_ptr Pointer to AES control block */
697 /* num_rounds Indicates total number of */
698 /* rounds for this operation. */
699 /* */
700 /* OUTPUT */
701 /* */
702 /* None */
703 /* */
704 /* CALLS */
705 /* */
706 /* None */
707 /* */
708 /* CALLED BY */
709 /* */
710 /* _nx_crypto_aes_encrypt Perform AES mode encryption */
711 /* */
712 /* RELEASE HISTORY */
713 /* */
714 /* DATE NAME DESCRIPTION */
715 /* */
716 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
717 /* 09-30-2020 Timothy Stapko Modified comment(s), */
718 /* resulting in version 6.1 */
719 /* */
720 /**************************************************************************/
_nx_crypto_aes_encryption_round(NX_CRYPTO_AES * aes_ptr,int num_rounds)721 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_encryption_round(NX_CRYPTO_AES *aes_ptr, int num_rounds)
722 {
723 UINT state_data[4];
724 UINT saved_state[4];
725
726 int round;
727
728
729 state_data[0] = aes_ptr -> nx_crypto_aes_state[0];
730 state_data[1] = aes_ptr -> nx_crypto_aes_state[1];
731 state_data[2] = aes_ptr -> nx_crypto_aes_state[2];
732 state_data[3] = aes_ptr -> nx_crypto_aes_state[3];
733
734 for (round = 1; round < num_rounds; round++)
735 {
736 /* make a copy of the state data. */
737
738 saved_state[0] = state_data[0];
739 saved_state[1] = state_data[1];
740 saved_state[2] = state_data[2];
741 saved_state[3] = state_data[3];
742
743 /*
744 The MixColumns operates on the state after rotation. The table below
745 illustrates the bytes before and after the ShiftRows operation.
746 This routine picks up bytes from its position BEFORE the rotation,
747 effectively combining SubBytes, ShiftRows, MixColumns, AddRoundKey
748 into one routine.
749
750 S00 S04 S08 S12 S00 S04 S08 S12
751
752 S01 S05 S09 S13 S05 S09 S13 S01
753 --->
754 S02 S06 S10 S14 S10 S14 S02 S06
755
756 S03 S07 S11 S15 S15 S03 S07 S11
757
758 The following code segment fully spells out the AES encryption, step by step.
759
760
761
762 S = bytes[ 0];
763 V0 = aes_encryption_table[S];
764 S = bytes[ 5];
765 val = aes_encryption_table[S];
766 V1 = LEFT_ROTATE24(val);
767 S = bytes[10];
768 val = aes_encryption_table[S];
769 V2 = LEFT_ROTATE16(val);
770 S = bytes[15];
771 val = aes_encryption_table[S];
772 V3 = LEFT_ROTATE8(val);
773 temp_state[0] = V0 ^ V1 ^ V2 ^ V3 ^ (aes_ptr -> nx_crypto_aes_key_schedule[round * 4]);
774
775 S = bytes[ 4];
776 V0 = aes_encryption_table[S];
777 S = bytes[ 9];
778 val = aes_encryption_table[S];
779 V1 = LEFT_ROTATE24(val);
780 S = bytes[14];
781 val = aes_encryption_table[S];
782 V2 = LEFT_ROTATE16(val);
783 S = bytes[ 3];
784 val = aes_encryption_table[S];
785 V3 = LEFT_ROTATE8(val);
786 temp_state[1] = V0 ^ V1 ^ V2 ^ V3 ^ (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 1]);
787
788
789 S = bytes[ 8];
790 V0 = aes_encryption_table[S];
791 S = bytes[13];
792 val = aes_encryption_table[S];
793 V1 = LEFT_ROTATE24(val);
794 S = bytes[ 2];
795 val = aes_encryption_table[S];
796 V2 = LEFT_ROTATE16(val);
797 S = bytes[ 7];
798 val = aes_encryption_table[S];
799 V3 = LEFT_ROTATE8(val);
800 temp_state[2] = V0 ^ V1 ^ V2 ^ V3 ^ (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 2]);
801
802 S = bytes[12];
803 V0 = aes_encryption_table[S];
804 S = bytes[ 1];
805 val = aes_encryption_table[S];
806 V1 = LEFT_ROTATE24(val);
807 S = bytes[ 6];
808 val = aes_encryption_table[S];
809 V2 = LEFT_ROTATE16(val);
810 S = bytes[11];
811 val = aes_encryption_table[S];
812 V3 = LEFT_ROTATE8(val);
813 temp_state[3] = V0 ^ V1 ^ V2 ^ V3 ^ (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 3]);
814
815 */
816
817 /* The following logic implements the steps above but could allow compiler to produce more
818 efficient code. */
819
820 state_data[0] = aes_encryption_table[EXTRACT_MSB_BYTE(saved_state[0])] ^
821 (LEFT_ROTATE24(aes_encryption_table[EXTRACT_2ND_BYTE(saved_state[1])])) ^
822 (LEFT_ROTATE16(aes_encryption_table[EXTRACT_3RD_BYTE(saved_state[2])])) ^
823 (LEFT_ROTATE8(aes_encryption_table[EXTRACT_LSB_BYTE(saved_state[3])])) ^
824 (aes_ptr -> nx_crypto_aes_key_schedule[round * 4]);
825
826 state_data[1] = aes_encryption_table[EXTRACT_MSB_BYTE(saved_state[1])] ^
827 (LEFT_ROTATE24(aes_encryption_table[EXTRACT_2ND_BYTE(saved_state[2])])) ^
828 (LEFT_ROTATE16(aes_encryption_table[EXTRACT_3RD_BYTE(saved_state[3])])) ^
829 (LEFT_ROTATE8(aes_encryption_table[EXTRACT_LSB_BYTE(saved_state[0])])) ^
830 (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 1]);
831
832 state_data[2] = aes_encryption_table[EXTRACT_MSB_BYTE(saved_state[2])] ^
833 (LEFT_ROTATE24(aes_encryption_table[EXTRACT_2ND_BYTE(saved_state[3])])) ^
834 (LEFT_ROTATE16(aes_encryption_table[EXTRACT_3RD_BYTE(saved_state[0])])) ^
835 (LEFT_ROTATE8(aes_encryption_table[EXTRACT_LSB_BYTE(saved_state[1])])) ^
836 (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 2]);
837
838 state_data[3] = aes_encryption_table[EXTRACT_MSB_BYTE(saved_state[3])] ^
839 (LEFT_ROTATE24(aes_encryption_table[EXTRACT_2ND_BYTE(saved_state[0])])) ^
840 (LEFT_ROTATE16(aes_encryption_table[EXTRACT_3RD_BYTE(saved_state[1])])) ^
841 (LEFT_ROTATE8(aes_encryption_table[EXTRACT_LSB_BYTE(saved_state[2])])) ^
842 (aes_ptr -> nx_crypto_aes_key_schedule[round * 4 + 3]);
843 }
844
845 /* Write the data back to state structure. */
846 aes_ptr -> nx_crypto_aes_state[0] = state_data[0];
847 aes_ptr -> nx_crypto_aes_state[1] = state_data[1];
848 aes_ptr -> nx_crypto_aes_state[2] = state_data[2];
849 aes_ptr -> nx_crypto_aes_state[3] = state_data[3];
850
851 #ifdef NX_SECURE_KEY_CLEAR
852 NX_CRYPTO_MEMSET(state_data, 0, sizeof(state_data));
853 NX_CRYPTO_MEMSET(saved_state, 0, sizeof(saved_state));
854 #endif /* NX_SECURE_KEY_CLEAR */
855 }
856
857 /**************************************************************************/
858 /* */
859 /* FUNCTION RELEASE */
860 /* */
861 /* _nx_crypto_aes_decryption_round PORTABLE C */
862 /* 6.1 */
863 /* AUTHOR */
864 /* */
865 /* Timothy Stapko, Microsoft Corporation */
866 /* */
867 /* DESCRIPTION */
868 /* */
869 /* This function combines the following operations: */
870 /* InvSubBytes(state) */
871 /* InvShiftrows(state) */
872 /* InvMixColumns(state) */
873 /* AddRoundKey(state, dw[round*Nb, (round+1)*Nb-1]) */
874 /* This step is the body of the loop in the middle of EqInvCipher. */
875 /* Refer to Figure 15 on page 25 of the AES Specification (Pub 197) */
876 /* */
877 /* INPUT */
878 /* */
879 /* aes_ptr Pointer to AES control block */
880 /* round Indicates the number of */
881 /* rounds of this iteration. */
882 /* */
883 /* OUTPUT */
884 /* */
885 /* None */
886 /* */
887 /* CALLS */
888 /* */
889 /* None */
890 /* */
891 /* CALLED BY */
892 /* */
893 /* _nx_crypto_aes_decrypt Perform AES mode decryption */
894 /* */
895 /* RELEASE HISTORY */
896 /* */
897 /* DATE NAME DESCRIPTION */
898 /* */
899 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
900 /* 09-30-2020 Timothy Stapko Modified comment(s), updated */
901 /* constants, resulting */
902 /* in version 6.1 */
903 /* */
904 /**************************************************************************/
_nx_crypto_aes_decryption_round(NX_CRYPTO_AES * aes_ptr,int round)905 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_decryption_round(NX_CRYPTO_AES *aes_ptr, int round)
906 {
907 UINT temp_state[4];
908 UCHAR *bytes = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
909 UINT *w = aes_ptr -> nx_crypto_aes_decrypt_key_schedule;
910 UINT V0, V1, V2, V3;
911
912 UCHAR S;
913 ULONG val;
914
915
916 /*
917 The InvMixColumns operates on the state after rotation. The table below
918 illustrates the bytes before and after the InvShiftRows operation.
919 This routine picks up bytes from its position BEFORE the rotation,
920 effectively combining InvSubBytes, InvShiftRows, InvMixColumns, AddRoundKey
921 into one routine.
922
923 S00 S04 S08 S12 S00 S04 S08 S12
924
925 S01 S05 S09 S13 S13 S01 S05 S09
926 --->
927 S02 S06 S10 S14 S10 S14 S02 S06
928
929 S03 S07 S11 S15 S07 S11 S15 S03
930 */
931 S = bytes[0];
932 V0 = aes_decryption_table[S];
933 S = bytes[13];
934 val = aes_decryption_table[S];
935 V1 = LEFT_ROTATE24(val);
936 S = bytes[10];
937 val = aes_decryption_table[S];
938 V2 = LEFT_ROTATE16(val);
939 S = bytes[7];
940 val = aes_decryption_table[S];
941 V3 = LEFT_ROTATE8(val);
942 temp_state[0] = V0 ^ V1 ^ V2 ^ V3 ^ (w[round * 4]);
943
944 S = bytes[4];
945 V0 = aes_decryption_table[S];
946 S = bytes[1];
947 val = aes_decryption_table[S];
948 V1 = LEFT_ROTATE24(val);
949 S = bytes[14];
950 val = aes_decryption_table[S];
951 V2 = LEFT_ROTATE16(val);
952 S = bytes[11];
953 val = aes_decryption_table[S];
954 V3 = LEFT_ROTATE8(val);
955 temp_state[1] = V0 ^ V1 ^ V2 ^ V3 ^ (w[round * 4 + 1]);
956
957 S = bytes[8];
958 V0 = aes_decryption_table[S];
959 S = bytes[5];
960 val = aes_decryption_table[S];
961 V1 = LEFT_ROTATE24(val);
962 S = bytes[2];
963 val = aes_decryption_table[S];
964 V2 = LEFT_ROTATE16(val);
965 S = bytes[15];
966 val = aes_decryption_table[S];
967 V3 = LEFT_ROTATE8(val);
968 temp_state[2] = V0 ^ V1 ^ V2 ^ V3 ^ (w[round * 4 + 2]);
969
970 S = bytes[12];
971 V0 = aes_decryption_table[S];
972 S = bytes[9];
973 val = aes_decryption_table[S];
974 V1 = LEFT_ROTATE24(val);
975 S = bytes[6];
976 val = aes_decryption_table[S];
977 V2 = LEFT_ROTATE16(val);
978 S = bytes[3];
979 val = aes_decryption_table[S];
980 V3 = LEFT_ROTATE8(val);
981 temp_state[3] = V0 ^ V1 ^ V2 ^ V3 ^ (w[round * 4 + 3]);
982
983 aes_ptr -> nx_crypto_aes_state[0] = temp_state[0];
984 aes_ptr -> nx_crypto_aes_state[1] = temp_state[1];
985 aes_ptr -> nx_crypto_aes_state[2] = temp_state[2];
986 aes_ptr -> nx_crypto_aes_state[3] = temp_state[3];
987
988 #ifdef NX_SECURE_KEY_CLEAR
989 NX_CRYPTO_MEMSET(temp_state, 0, sizeof(temp_state));
990 #endif /* NX_SECURE_KEY_CLEAR */
991 }
992
993
994 /**************************************************************************/
995 /* */
996 /* FUNCTION RELEASE */
997 /* */
998 /* _nx_crypto_aes_encrypt PORTABLE C */
999 /* 6.1 */
1000 /* AUTHOR */
1001 /* */
1002 /* Timothy Stapko, Microsoft Corporation */
1003 /* */
1004 /* DESCRIPTION */
1005 /* */
1006 /* This function performs AES encryption on a block of 16 byte message */
1007 /* pointed to by "input", and the encrypted text is stored in buffer */
1008 /* pointed to by "output". The size of the output buffer must be at */
1009 /* least 16 bytes. The output buffer may point to the same input */
1010 /* buffer, in which case the encrypted text overwrites the input */
1011 /* message. */
1012 /* */
1013 /* INPUT */
1014 /* */
1015 /* aes_ptr Pointer to AES control block */
1016 /* input Pointer to an input message */
1017 /* of 16 bytes. */
1018 /* output Pointer to an output buffer */
1019 /* for storing the encrypted */
1020 /* message. The output buffer */
1021 /* must be at least 16 bytes. */
1022 /* length The length of output buffer */
1023 /* */
1024 /* OUTPUT */
1025 /* */
1026 /* status Completion status */
1027 /* */
1028 /* CALLS */
1029 /* */
1030 /* _nx_seucre_aes_add_round_key Perform AddRoundKey operation */
1031 /* _nx_crypto_aes_encryption_round The main body of AES */
1032 /* encryption */
1033 /* _nx_crypto_aes_sub_shift_roundkey Perform the last step in AES */
1034 /* encryption operation */
1035 /* */
1036 /* CALLED BY */
1037 /* */
1038 /* Application Code */
1039 /* */
1040 /* RELEASE HISTORY */
1041 /* */
1042 /* DATE NAME DESCRIPTION */
1043 /* */
1044 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1045 /* 09-30-2020 Timothy Stapko Modified comment(s), disabled */
1046 /* unaligned access by default,*/
1047 /* resulting in version 6.1 */
1048 /* */
1049 /**************************************************************************/
_nx_crypto_aes_encrypt(NX_CRYPTO_AES * aes_ptr,UCHAR * input,UCHAR * output,UINT length)1050 NX_CRYPTO_KEEP UINT _nx_crypto_aes_encrypt(NX_CRYPTO_AES *aes_ptr, UCHAR *input, UCHAR *output, UINT length)
1051 {
1052 UINT num_rounds;
1053 UINT *w;
1054 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1055 UCHAR *aes_state;
1056 #else
1057 UINT *buf;
1058 #endif
1059
1060
1061 NX_CRYPTO_PARAMETER_NOT_USED(length);
1062
1063 w = aes_ptr -> nx_crypto_aes_key_schedule;
1064
1065 num_rounds = aes_ptr -> nx_crypto_aes_rounds;
1066
1067 if (num_rounds < 10 || num_rounds > 14)
1068 {
1069 return(NX_CRYPTO_INVALID_PARAMETER);
1070 }
1071
1072 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1073 aes_state = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
1074 aes_state[0] = input[0];
1075 aes_state[1] = input[1];
1076 aes_state[2] = input[2];
1077 aes_state[3] = input[3];
1078 aes_state[4] = input[4];
1079 aes_state[5] = input[5];
1080 aes_state[6] = input[6];
1081 aes_state[7] = input[7];
1082 aes_state[8] = input[8];
1083 aes_state[9] = input[9];
1084 aes_state[10] = input[10];
1085 aes_state[11] = input[11];
1086 aes_state[12] = input[12];
1087 aes_state[13] = input[13];
1088 aes_state[14] = input[14];
1089 aes_state[15] = input[15];
1090 #else
1091 buf = (UINT *)input;
1092 aes_ptr -> nx_crypto_aes_state[0] = buf[0];
1093 aes_ptr -> nx_crypto_aes_state[1] = buf[1];
1094 aes_ptr -> nx_crypto_aes_state[2] = buf[2];
1095 aes_ptr -> nx_crypto_aes_state[3] = buf[3];
1096 #endif
1097
1098 _nx_crypto_aes_add_round_key(aes_ptr, &w[0]);
1099
1100 _nx_crypto_aes_encryption_round(aes_ptr, (INT)num_rounds);
1101
1102 _nx_crypto_aes_sub_shift_roundkey(aes_ptr, &w[num_rounds * 4]);
1103
1104
1105 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1106 output[0] = aes_state[0];
1107 output[1] = aes_state[1];
1108 output[2] = aes_state[2];
1109 output[3] = aes_state[3];
1110 output[4] = aes_state[4];
1111 output[5] = aes_state[5];
1112 output[6] = aes_state[6];
1113 output[7] = aes_state[7];
1114 output[8] = aes_state[8];
1115 output[9] = aes_state[9];
1116 output[10] = aes_state[10];
1117 output[11] = aes_state[11];
1118 output[12] = aes_state[12];
1119 output[13] = aes_state[13];
1120 output[14] = aes_state[14];
1121 output[15] = aes_state[15];
1122 #else
1123 buf = (UINT *)output;
1124 buf[0] = aes_ptr -> nx_crypto_aes_state[0];
1125 buf[1] = aes_ptr -> nx_crypto_aes_state[1];
1126 buf[2] = aes_ptr -> nx_crypto_aes_state[2];
1127 buf[3] = aes_ptr -> nx_crypto_aes_state[3];
1128 #endif
1129
1130 return(NX_CRYPTO_SUCCESS);
1131 }
1132
1133
1134 /**************************************************************************/
1135 /* Key expansion routines */
1136 /**************************************************************************/
1137 /**************************************************************************/
1138 /* */
1139 /* FUNCTION RELEASE */
1140 /* */
1141 /* _nx_crypto_aes_subword PORTABLE C */
1142 /* 6.1 */
1143 /* AUTHOR */
1144 /* */
1145 /* Timothy Stapko, Microsoft Corporation */
1146 /* */
1147 /* DESCRIPTION */
1148 /* */
1149 /* This function performs SubBytes(state) operation according to */
1150 /* section 5.1.1 on page 15 of the AES specification (Pub 197) */
1151 /* */
1152 /* INPUT */
1153 /* */
1154 /* word The input 4-byte word */
1155 /* */
1156 /* OUTPUT */
1157 /* */
1158 /* UINT word The value after being */
1159 /* substituted. */
1160 /* */
1161 /* CALLS */
1162 /* */
1163 /* None */
1164 /* */
1165 /* CALLED BY */
1166 /* */
1167 /* _nx_crypto_aes_key_expansion AES key expansion */
1168 /* */
1169 /* RELEASE HISTORY */
1170 /* */
1171 /* DATE NAME DESCRIPTION */
1172 /* */
1173 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1174 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1175 /* resulting in version 6.1 */
1176 /* */
1177 /**************************************************************************/
_nx_crypto_aes_subword(UINT word)1178 NX_CRYPTO_KEEP static UINT _nx_crypto_aes_subword(UINT word)
1179 {
1180 UINT result;
1181
1182 result = sub_bytes_sbox[word & 0xFF];
1183 result |= (UINT)((sub_bytes_sbox[(word & 0x0000FF00) >> 8]) << 8);
1184 result |= (UINT)((sub_bytes_sbox[(word & 0x00FF0000) >> 16]) << 16);
1185 result |= (UINT)((sub_bytes_sbox[(word & 0xFF000000) >> 24]) << 24);
1186 return result;
1187 }
1188
1189 /**************************************************************************/
1190 /* */
1191 /* FUNCTION RELEASE */
1192 /* */
1193 /* _nx_crypto_aes_key_expansion PORTABLE C */
1194 /* 6.1 */
1195 /* AUTHOR */
1196 /* */
1197 /* Timothy Stapko, Microsoft Corporation */
1198 /* */
1199 /* DESCRIPTION */
1200 /* */
1201 /* This routine performs AES Key Expansion as outlined in seciton 5.2 */
1202 /* on page 195 of the AES specification (Pub 197) */
1203 /* */
1204 /* INPUT */
1205 /* */
1206 /* aes_ptr Pointer to AES control block */
1207 /* */
1208 /* OUTPUT */
1209 /* */
1210 /* None */
1211 /* */
1212 /* CALLS */
1213 /* */
1214 /* _nx_crypto_aes_subword Apply sbox substitution */
1215 /* */
1216 /* CALLED BY */
1217 /* */
1218 /* _nx_crypto_aes_key_set Set AES crypto key */
1219 /* */
1220 /* RELEASE HISTORY */
1221 /* */
1222 /* DATE NAME DESCRIPTION */
1223 /* */
1224 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1225 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1226 /* resulting in version 6.1 */
1227 /* */
1228 /**************************************************************************/
_nx_crypto_aes_key_expansion(NX_CRYPTO_AES * aes_ptr)1229 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_key_expansion(NX_CRYPTO_AES *aes_ptr)
1230 {
1231 UINT temp;
1232 UINT i;
1233 UINT iterations = 0;
1234 UINT loop_count;
1235 UINT *expanded_key;
1236 UINT key_size;
1237
1238 expanded_key = aes_ptr -> nx_crypto_aes_key_schedule;
1239
1240 key_size = aes_ptr -> nx_crypto_aes_key_size;
1241
1242 switch (key_size)
1243 {
1244 case NX_CRYPTO_AES_KEY_SIZE_128_BITS:
1245 iterations = 9;
1246 break;
1247 case NX_CRYPTO_AES_KEY_SIZE_192_BITS:
1248 iterations = 7;
1249 break;
1250
1251 /* case NX_CRYPTO_AES_KEY_SIZE_256_BITS: */
1252 default:
1253 iterations = 6;
1254 break;
1255 }
1256
1257 temp = expanded_key[key_size - 1];
1258 /* Expand the key schedule from the initial key. */
1259 i = key_size;
1260 for (loop_count = 0; loop_count < iterations; loop_count++)
1261 {
1262
1263 temp = LEFT_ROTATE8(temp); /* (temp << 8) | (temp >> 24); */
1264 temp = _nx_crypto_aes_subword(temp);
1265 temp ^= SET_MSB_BYTE((UINT)aes_rcon_array[loop_count]); /* (((UINT)aes_rcon_array[loop_count]) << 24); */
1266 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1267 switch (key_size)
1268 {
1269 case NX_CRYPTO_AES_KEY_SIZE_256_BITS:
1270 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1271 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1272 /* AES KEY 256 bits: fall through the rest of the statement to complete
1273 one iteration of key expansion. */ /* fallthrough */
1274 case NX_CRYPTO_AES_KEY_SIZE_192_BITS:
1275 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1276
1277 /* Special case for AES 256: Need an extra subword operation on 4th step. */
1278 if (key_size == NX_CRYPTO_AES_KEY_SIZE_256_BITS)
1279 {
1280 temp = _nx_crypto_aes_subword(temp);
1281 }
1282 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1283 /* AES KEY 256 and 192 bits: fall through the rest of the statement to complete
1284 one iteration of key expansion. */ /* fallthrough */
1285 /* case NX_CRYPTO_AES_KEY_SIZE_128_BITS: */
1286 default:
1287 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1288 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1289 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1290 break;
1291 }
1292 }
1293 /* Last round. */
1294 temp = LEFT_ROTATE8(temp); /* (temp << 8) | (temp >> 24); */
1295 temp = _nx_crypto_aes_subword(temp);
1296 temp ^= SET_MSB_BYTE((UINT)aes_rcon_array[loop_count]); /* (((UINT)aes_rcon_array[loop_count]) << 24); */
1297 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1298 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1299 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1300 temp = expanded_key[i - key_size] ^ temp; expanded_key[i] = temp; i++;
1301
1302 #ifdef NX_SECURE_KEY_CLEAR
1303 temp = 0;
1304 #endif /* NX_SECURE_KEY_CLEAR */
1305
1306 return;
1307 }
1308
1309 /**************************************************************************/
1310 /* */
1311 /* FUNCTION RELEASE */
1312 /* */
1313 /* _nx_crypto_aes_key_expansion_inverse PORTABLE C */
1314 /* 6.1.10 */
1315 /* AUTHOR */
1316 /* */
1317 /* Timothy Stapko, Microsoft Corporation */
1318 /* */
1319 /* DESCRIPTION */
1320 /* */
1321 /* This routine performs AES Key Expansion as outlined in seciton 5.2 */
1322 /* on page 195 of the AES specification (Pub 197) */
1323 /* */
1324 /* Note on the decryption side, NetX Crypto AES uses Equivalent */
1325 /* Inverse Cipher (section 5.3.5 in Pub 197). Therefore the inverse */
1326 /* key expansion starts with the regular key expansion then apply */
1327 /* InvMixClumns(state). (Page 24 Pub 197). */
1328 /* */
1329 /* INPUT */
1330 /* */
1331 /* aes_ptr Pointer to AES control block */
1332 /* */
1333 /* OUTPUT */
1334 /* */
1335 /* None */
1336 /* */
1337 /* CALLS */
1338 /* */
1339 /* None */
1340 /* */
1341 /* CALLED BY */
1342 /* */
1343 /* _nx_crypto_aes_key_set Set AES crypto key */
1344 /* */
1345 /* RELEASE HISTORY */
1346 /* */
1347 /* DATE NAME DESCRIPTION */
1348 /* */
1349 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1350 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1351 /* resulting in version 6.1 */
1352 /* 01-31-2022 Timothy Stapko Modified comment(s), */
1353 /* moved inverse key expansion,*/
1354 /* resulting in version 6.1.10 */
1355 /* */
1356 /**************************************************************************/
_nx_crypto_aes_key_expansion_inverse(NX_CRYPTO_AES * aes_ptr)1357 NX_CRYPTO_KEEP static VOID _nx_crypto_aes_key_expansion_inverse(NX_CRYPTO_AES *aes_ptr)
1358 {
1359 UINT i;
1360 UINT num_rounds;
1361 UINT *expanded_key;
1362 UINT V0, V1, V2, V3;
1363
1364 UCHAR S;
1365 ULONG val;
1366 ULONG key;
1367
1368 expanded_key = aes_ptr -> nx_crypto_aes_decrypt_key_schedule;
1369
1370 num_rounds = aes_ptr -> nx_crypto_aes_rounds;
1371
1372 /* Copy the 1st set of keys */
1373 for (i = 0; i < 4; i++)
1374 {
1375 aes_ptr -> nx_crypto_aes_decrypt_key_schedule[i] = aes_ptr -> nx_crypto_aes_key_schedule[i];
1376 }
1377
1378 for (; i < 4 * (num_rounds); i++)
1379 {
1380
1381 /* Pick up the key value from key_schedule[]. */
1382 key = aes_ptr -> nx_crypto_aes_key_schedule[i];
1383 S = EXTRACT_MSB_BYTE(key); /* (key >> 24) & 0xFF; */
1384
1385 /* Performs InvMixColumns() operation by using the look up table. */
1386 V0 = aes_inv_mix_table[S];
1387
1388 S = EXTRACT_2ND_BYTE(key); /* (key >> 16) & 0xFF; */
1389 val = aes_inv_mix_table[S];
1390 V1 = LEFT_ROTATE24(val); /* (val >> 8) | (val << 24); */
1391
1392 S = EXTRACT_3RD_BYTE(key); /* (key >> 8) & 0xFF;*/
1393 val = aes_inv_mix_table[S];
1394 V2 = LEFT_ROTATE16(val); /* (val >> 16) | (val << 16); */
1395
1396 S = (UCHAR)EXTRACT_LSB_BYTE(key); /* key & 0xFF; */
1397 val = aes_inv_mix_table[S];
1398 V3 = LEFT_ROTATE8(val); /* (val >> 24) | (val << 8);*/
1399
1400 /* Put values together */
1401 key = V0 ^ V1 ^ V2 ^ V3;
1402
1403 /* Stores the expanded key (after applying InvMixColumns()) */
1404 expanded_key[i] = key;
1405 }
1406
1407 /* No need to perform InvMixColums() on the last 4 words. */
1408 expanded_key[i] = aes_ptr -> nx_crypto_aes_key_schedule[i];
1409 expanded_key[i + 1] = aes_ptr -> nx_crypto_aes_key_schedule[i + 1];
1410 expanded_key[i + 2] = aes_ptr -> nx_crypto_aes_key_schedule[i + 2];
1411 expanded_key[i + 3] = aes_ptr -> nx_crypto_aes_key_schedule[i + 3];
1412
1413 /* Set the inverse key expansion flag. */
1414 aes_ptr -> nx_crypto_aes_inverse_key_expanded = 1;
1415
1416 #ifdef NX_SECURE_KEY_CLEAR
1417 key = 0;
1418 #endif /* NX_SECURE_KEY_CLEAR */
1419
1420 return;
1421 }
1422
1423
1424 /**************************************************************************/
1425 /* Decryption routines */
1426 /**************************************************************************/
1427
1428
1429
1430
1431 /*
1432
1433 __ __ __ __ __ __
1434 | S0'| | 0e 0b 0d 09| | S0 |
1435 | S1'| | 09 0e 0b 0d| | S1 |
1436 | S2'| = | 0d 09 0e 0b| | S2 |
1437 | S3'| | 0b 0d 09 0e| | S3 |
1438 -- -- -- -- -- --
1439
1440 S' = V0 ^ V1 ^ V2 ^ V3
1441 S0' = {0e}*S0 ^ {0b}*S1 ^ {0d}*S2 ^ {09}*S3
1442 S1' = {09}*S0 ^ {0e}*S1 ^ {0b}*S2 ^ {0d}*S3
1443 S2' = {0d}*S0 ^ {09}*S1 ^ {0e}*S2 ^ {0b}*S3
1444 S3' = {0b}*S0 ^ {0d}*S1 ^ {09}*S2 ^ {0e}*S3
1445
1446
1447 */
1448
1449
1450 /**************************************************************************/
1451 /* */
1452 /* FUNCTION RELEASE */
1453 /* */
1454 /* _nx_crypto_aes_decrypt PORTABLE C */
1455 /* 6.1.10 */
1456 /* AUTHOR */
1457 /* */
1458 /* Timothy Stapko, Microsoft Corporation */
1459 /* */
1460 /* DESCRIPTION */
1461 /* */
1462 /* This function performs AES decryption on a block of 16 byte message */
1463 /* pointed to by "input", and the decrypted text is stored in buffer */
1464 /* pointed to by "output". The size of the output buffer must be at */
1465 /* least 16 bytes. The output buffer may point to the same input */
1466 /* buffer, in which case the decrypted text overwrites the input */
1467 /* message. */
1468 /* */
1469 /* INPUT */
1470 /* */
1471 /* aes_ptr Pointer to AES control block */
1472 /* input Pointer to an input message */
1473 /* of 16 bytes. */
1474 /* output Pointer to an output buffer */
1475 /* for storing the decrypted */
1476 /* message. The output buffer */
1477 /* must be at least 16 bytes. */
1478 /* length The length of output buffer */
1479 /* */
1480 /* OUTPUT */
1481 /* */
1482 /* status Completion status */
1483 /* */
1484 /* CALLS */
1485 /* */
1486 /* _nx_seucre_aes_add_round_key Perform AddRoundKey operation */
1487 /* _nx_crypto_aes_decryption_round The main body of AES */
1488 /* decryption */
1489 /* _nx_crypto_aes_inv_sub_shift_roundkey Perform the last step in AES */
1490 /* decryption operation */
1491 /* */
1492 /* CALLED BY */
1493 /* */
1494 /* Application Code */
1495 /* */
1496 /* RELEASE HISTORY */
1497 /* */
1498 /* DATE NAME DESCRIPTION */
1499 /* */
1500 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1501 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1502 /* resulting in version 6.1 */
1503 /* 01-31-2022 Timothy Stapko Modified comment(s), */
1504 /* moved inverse key expansion,*/
1505 /* resulting in version 6.1.10 */
1506 /* */
1507 /**************************************************************************/
_nx_crypto_aes_decrypt(NX_CRYPTO_AES * aes_ptr,UCHAR * input,UCHAR * output,UINT length)1508 NX_CRYPTO_KEEP UINT _nx_crypto_aes_decrypt(NX_CRYPTO_AES *aes_ptr, UCHAR *input, UCHAR *output, UINT length)
1509 {
1510 UINT num_rounds;
1511 UINT round;
1512 UINT *w;
1513 UINT *v;
1514 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1515 UCHAR *aes_state;
1516 #else
1517 UINT *buf;
1518 #endif
1519
1520
1521 NX_CRYPTO_PARAMETER_NOT_USED(length);
1522
1523 /* If the flag is not set, we assume the inverse key expansion
1524 table is not created yet. Call the routine to create one. */
1525 if(aes_ptr -> nx_crypto_aes_inverse_key_expanded == 0)
1526 {
1527 _nx_crypto_aes_key_expansion_inverse(aes_ptr);
1528 }
1529
1530
1531 w = aes_ptr -> nx_crypto_aes_decrypt_key_schedule;
1532 v = aes_ptr -> nx_crypto_aes_key_schedule;
1533
1534 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1535 aes_state = (UCHAR *)aes_ptr -> nx_crypto_aes_state;
1536 aes_state[0] = input[0];
1537 aes_state[1] = input[1];
1538 aes_state[2] = input[2];
1539 aes_state[3] = input[3];
1540 aes_state[4] = input[4];
1541 aes_state[5] = input[5];
1542 aes_state[6] = input[6];
1543 aes_state[7] = input[7];
1544 aes_state[8] = input[8];
1545 aes_state[9] = input[9];
1546 aes_state[10] = input[10];
1547 aes_state[11] = input[11];
1548 aes_state[12] = input[12];
1549 aes_state[13] = input[13];
1550 aes_state[14] = input[14];
1551 aes_state[15] = input[15];
1552 #else
1553 buf = (UINT *)input;
1554 aes_ptr -> nx_crypto_aes_state[0] = buf[0];
1555 aes_ptr -> nx_crypto_aes_state[1] = buf[1];
1556 aes_ptr -> nx_crypto_aes_state[2] = buf[2];
1557 aes_ptr -> nx_crypto_aes_state[3] = buf[3];
1558 #endif
1559
1560
1561 num_rounds = aes_ptr -> nx_crypto_aes_rounds;
1562
1563 if (num_rounds < 10 || num_rounds > 14)
1564 {
1565 return(NX_CRYPTO_INVALID_PARAMETER);
1566 }
1567
1568 _nx_crypto_aes_add_round_key(aes_ptr, &v[num_rounds * 4]);
1569
1570 for (round = num_rounds - 1; round >= 1; --round)
1571 {
1572
1573 _nx_crypto_aes_decryption_round(aes_ptr, (INT)round);
1574 }
1575
1576 _nx_crypto_aes_inv_sub_shift_roundkey(aes_ptr, &w[0]);
1577
1578 /* Extract the output encrypted block. */
1579 #ifndef NX_CRYPTO_ENABLE_UNALIGNED_ACCESS
1580 output[0] = aes_state[0];
1581 output[1] = aes_state[1];
1582 output[2] = aes_state[2];
1583 output[3] = aes_state[3];
1584 output[4] = aes_state[4];
1585 output[5] = aes_state[5];
1586 output[6] = aes_state[6];
1587 output[7] = aes_state[7];
1588 output[8] = aes_state[8];
1589 output[9] = aes_state[9];
1590 output[10] = aes_state[10];
1591 output[11] = aes_state[11];
1592 output[12] = aes_state[12];
1593 output[13] = aes_state[13];
1594 output[14] = aes_state[14];
1595 output[15] = aes_state[15];
1596 #else
1597 buf = (UINT *)output;
1598 buf[0] = aes_ptr -> nx_crypto_aes_state[0];
1599 buf[1] = aes_ptr -> nx_crypto_aes_state[1];
1600 buf[2] = aes_ptr -> nx_crypto_aes_state[2];
1601 buf[3] = aes_ptr -> nx_crypto_aes_state[3];
1602 #endif
1603
1604 return(NX_CRYPTO_SUCCESS);
1605 }
1606
1607
1608 /**************************************************************************/
1609 /* */
1610 /* FUNCTION RELEASE */
1611 /* */
1612 /* _nx_crypto_aes_key_set PORTABLE C */
1613 /* 6.1.10 */
1614 /* AUTHOR */
1615 /* */
1616 /* Timothy Stapko, Microsoft Corporation */
1617 /* */
1618 /* DESCRIPTION */
1619 /* */
1620 /* This function configures key for AES encryption and decryption. */
1621 /* */
1622 /* INPUT */
1623 /* */
1624 /* aes_ptr Pointer to AES control block */
1625 /* key Pointer to key string */
1626 /* key_size Size of the key, valid values */
1627 /* are: */
1628 /* NX_CRYPTO_AES_KEY_SIZE_128_BITS */
1629 /* NX_CRYPTO_AES_KEY_SIZE_192_BITS */
1630 /* NX_CRYPTO_AES_KEY_SIZE_256_BITS */
1631 /* */
1632 /* OUTPUT */
1633 /* */
1634 /* status Completion status */
1635 /* */
1636 /* CALLS */
1637 /* */
1638 /* _nx_crypto_aes_key_expansion Key expansion for encryption */
1639 /* _nx_crypto_aes_key_expansion_inverse Key expansion for decryption */
1640 /* */
1641 /* CALLED BY */
1642 /* */
1643 /* Application Code */
1644 /* */
1645 /* RELEASE HISTORY */
1646 /* */
1647 /* DATE NAME DESCRIPTION */
1648 /* */
1649 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1650 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1651 /* resulting in version 6.1 */
1652 /* 01-31-2022 Timothy Stapko Modified comment(s), */
1653 /* moved inverse key expansion,*/
1654 /* resulting in version 6.1.10 */
1655 /* */
1656 /**************************************************************************/
_nx_crypto_aes_key_set(NX_CRYPTO_AES * aes_ptr,UCHAR * key,UINT key_size)1657 NX_CRYPTO_KEEP UINT _nx_crypto_aes_key_set(NX_CRYPTO_AES *aes_ptr, UCHAR *key, UINT key_size)
1658 {
1659 UCHAR *expanded_key;
1660 UINT i;
1661
1662 /* Set the AES key size (should be in 32-bit *words*). */
1663 aes_ptr -> nx_crypto_aes_key_size = (USHORT)key_size;
1664
1665 expanded_key = (UCHAR *)aes_ptr -> nx_crypto_aes_key_schedule;
1666
1667 /* Copy the key into the beginning of the expanded key buffer. */
1668 for (i = 0; i < key_size * 4; ++i)
1669 {
1670 expanded_key[i] = key[i];
1671 }
1672
1673 /* Based on the key size, determine the number of rounds. */
1674 switch (key_size)
1675 {
1676 case NX_CRYPTO_AES_KEY_SIZE_128_BITS:
1677 aes_ptr -> nx_crypto_aes_rounds = 10;
1678 break;
1679 case NX_CRYPTO_AES_KEY_SIZE_192_BITS:
1680 aes_ptr -> nx_crypto_aes_rounds = 12;
1681 break;
1682 /* case NX_CRYPTO_AES_KEY_SIZE_256_BITS: */
1683 default:
1684 aes_ptr -> nx_crypto_aes_rounds = 14;
1685 break;
1686 }
1687
1688
1689 _nx_crypto_aes_key_expansion(aes_ptr);
1690
1691 /* Move key_expansion_inverse into the decrypt logic.
1692 No reason to build the inverse table if the application doesn't do decryption. */
1693 /* Clear the inverse key expansion flag; */
1694 aes_ptr -> nx_crypto_aes_inverse_key_expanded = 0;
1695
1696 return(NX_CRYPTO_SUCCESS);
1697 }
1698
1699 /**************************************************************************/
1700 /* */
1701 /* FUNCTION RELEASE */
1702 /* */
1703 /* _nx_crypto_method_aes_init PORTABLE C */
1704 /* 6.3.0 */
1705 /* AUTHOR */
1706 /* */
1707 /* Timothy Stapko, Microsoft Corporation */
1708 /* */
1709 /* DESCRIPTION */
1710 /* */
1711 /* This function initializes the AES crypto module. */
1712 /* */
1713 /* INPUT */
1714 /* */
1715 /* method Crypto Method Object */
1716 /* key Key */
1717 /* key_size_in_bits Size of the key, in bits */
1718 /* handle Handle, specified by user */
1719 /* crypto_metadata Metadata area */
1720 /* crypto_metadata_size Size of the metadata area */
1721 /* */
1722 /* OUTPUT */
1723 /* */
1724 /* status Completion status */
1725 /* */
1726 /* CALLS */
1727 /* */
1728 /* _nx_crypto_aes_key_set Set the key for AES */
1729 /* */
1730 /* CALLED BY */
1731 /* */
1732 /* _nx_crypto_method_aes_operation Handle AES encrypt or decrypt */
1733 /* */
1734 /* RELEASE HISTORY */
1735 /* */
1736 /* DATE NAME DESCRIPTION */
1737 /* */
1738 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1739 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1740 /* resulting in version 6.1 */
1741 /* 10-31-2023 Yanwu Cai Modified comment(s), */
1742 /* resulting in version 6.3.0 */
1743 /* */
1744 /**************************************************************************/
_nx_crypto_method_aes_init(struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,VOID ** handle,VOID * crypto_metadata,ULONG crypto_metadata_size)1745 NX_CRYPTO_KEEP UINT _nx_crypto_method_aes_init(struct NX_CRYPTO_METHOD_STRUCT *method,
1746 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
1747 VOID **handle,
1748 VOID *crypto_metadata,
1749 ULONG crypto_metadata_size)
1750 {
1751
1752 NX_CRYPTO_PARAMETER_NOT_USED(handle);
1753
1754 NX_CRYPTO_STATE_CHECK
1755
1756
1757 if ((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
1758 {
1759 return(NX_CRYPTO_PTR_ERROR);
1760 }
1761
1762 /* Verify the metadata address is 4-byte aligned. */
1763 if((((ULONG)crypto_metadata) & 0x3) != 0)
1764 {
1765 return(NX_CRYPTO_PTR_ERROR);
1766 }
1767
1768 if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
1769 {
1770 return(NX_CRYPTO_PTR_ERROR);
1771 }
1772
1773 /* We only support 128-bit or 256-bit key size for the time-being. */
1774 if ((key_size_in_bits != NX_CRYPTO_AES_128_KEY_LEN_IN_BITS) && (key_size_in_bits != NX_CRYPTO_AES_192_KEY_LEN_IN_BITS) && (key_size_in_bits != NX_CRYPTO_AES_256_KEY_LEN_IN_BITS))
1775 {
1776 return(NX_CRYPTO_UNSUPPORTED_KEY_SIZE);
1777 }
1778
1779 NX_CRYPTO_MEMSET(&((NX_CRYPTO_AES *)crypto_metadata) -> nx_crypto_aes_mode_context, 0, sizeof(((NX_CRYPTO_AES *)crypto_metadata) -> nx_crypto_aes_mode_context));
1780
1781 _nx_crypto_aes_key_set((NX_CRYPTO_AES *)crypto_metadata, key, key_size_in_bits >> 5);
1782
1783 return(NX_CRYPTO_SUCCESS);
1784 }
1785
1786
1787 /**************************************************************************/
1788 /* */
1789 /* FUNCTION RELEASE */
1790 /* */
1791 /* _nx_crypto_method_aes_cleanup PORTABLE C */
1792 /* 6.1 */
1793 /* AUTHOR */
1794 /* */
1795 /* Timothy Stapko, Microsoft Corporation */
1796 /* */
1797 /* DESCRIPTION */
1798 /* */
1799 /* This function cleans up the crypto metadata. */
1800 /* */
1801 /* INPUT */
1802 /* */
1803 /* crypto_metadata Crypto metadata */
1804 /* */
1805 /* OUTPUT */
1806 /* */
1807 /* status Completion status */
1808 /* */
1809 /* CALLS */
1810 /* */
1811 /* NX_CRYPTO_MEMSET Set the memory */
1812 /* */
1813 /* CALLED BY */
1814 /* */
1815 /* Application Code */
1816 /* */
1817 /* RELEASE HISTORY */
1818 /* */
1819 /* DATE NAME DESCRIPTION */
1820 /* */
1821 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1822 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1823 /* resulting in version 6.1 */
1824 /* */
1825 /**************************************************************************/
_nx_crypto_method_aes_cleanup(VOID * crypto_metadata)1826 NX_CRYPTO_KEEP UINT _nx_crypto_method_aes_cleanup(VOID *crypto_metadata)
1827 {
1828
1829 NX_CRYPTO_STATE_CHECK
1830
1831 #ifdef NX_SECURE_KEY_CLEAR
1832 if (!crypto_metadata)
1833 return (NX_CRYPTO_SUCCESS);
1834
1835 /* Clean up the crypto metadata. */
1836 NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_AES));
1837 #else
1838 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
1839 #endif /* NX_SECURE_KEY_CLEAR */
1840
1841 return(NX_CRYPTO_SUCCESS);
1842 }
1843
1844
1845 /**************************************************************************/
1846 /* */
1847 /* FUNCTION RELEASE */
1848 /* */
1849 /* _nx_crypto_method_aes_operation PORTABLE C */
1850 /* 6.3.0 */
1851 /* AUTHOR */
1852 /* */
1853 /* Timothy Stapko, Microsoft Corporation */
1854 /* */
1855 /* DESCRIPTION */
1856 /* */
1857 /* This function encrypts and decrypts a message using */
1858 /* the AES algorithm. */
1859 /* */
1860 /* INPUT */
1861 /* */
1862 /* op AES operation */
1863 /* handle Crypto handle */
1864 /* method Cryption Method Object */
1865 /* key Encryption Key */
1866 /* key_size_in_bits Key size in bits */
1867 /* input Input data */
1868 /* input_length_in_byte Input data size */
1869 /* iv_ptr Initial vector */
1870 /* output Output buffer */
1871 /* output_length_in_byte Output buffer size */
1872 /* crypto_metadata Metadata area */
1873 /* crypto_metadata_size Metadata area size */
1874 /* packet_ptr Pointer to packet */
1875 /* nx_crypto_hw_process_callback Callback function pointer */
1876 /* */
1877 /* OUTPUT */
1878 /* */
1879 /* status Completion status */
1880 /* */
1881 /* CALLS */
1882 /* */
1883 /* _nx_crypto_method_aes_cbc_operation Handle AES CBC operation */
1884 /* _nx_crypto_method_aes_ccm_operation Handle AES CCM operation */
1885 /* _nx_crypto_method_aes_gcm_operation Handle AES GCM operation */
1886 /* _nx_crypto_method_aes_ctr_operation Handle AES CTR operation */
1887 /* _nx_crypto_method_aes_xcbc_operation Handle AES XCBC operation */
1888 /* */
1889 /* CALLED BY */
1890 /* */
1891 /* Application Code */
1892 /* */
1893 /* RELEASE HISTORY */
1894 /* */
1895 /* DATE NAME DESCRIPTION */
1896 /* */
1897 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1898 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1899 /* resulting in version 6.1 */
1900 /* 10-31-2023 Yanwu Cai Modified comment(s), */
1901 /* resulting in version 6.3.0 */
1902 /* */
1903 /**************************************************************************/
_nx_crypto_method_aes_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))1904 NX_CRYPTO_KEEP UINT _nx_crypto_method_aes_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
1905 VOID *handle, /* Crypto handler */
1906 struct NX_CRYPTO_METHOD_STRUCT *method,
1907 UCHAR *key,
1908 NX_CRYPTO_KEY_SIZE key_size_in_bits,
1909 UCHAR *input,
1910 ULONG input_length_in_byte,
1911 UCHAR *iv_ptr,
1912 UCHAR *output,
1913 ULONG output_length_in_byte,
1914 VOID *crypto_metadata,
1915 ULONG crypto_metadata_size,
1916 VOID *packet_ptr,
1917 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
1918 {
1919 UINT status;
1920
1921 NX_CRYPTO_STATE_CHECK
1922
1923 /* Verify the metadata address is 4-byte aligned. */
1924 if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
1925 {
1926 return(NX_CRYPTO_PTR_ERROR);
1927 }
1928
1929 if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
1930 {
1931 return(NX_CRYPTO_PTR_ERROR);
1932 }
1933
1934 /* Check if the algorithm is cbc or ctr. */
1935 if (method -> nx_crypto_algorithm == NX_CRYPTO_ENCRYPTION_AES_CBC)
1936 {
1937
1938 /* AES CBC */
1939 status = _nx_crypto_method_aes_cbc_operation(op, handle, method, key, key_size_in_bits,
1940 input, input_length_in_byte, iv_ptr,
1941 output, output_length_in_byte,
1942 crypto_metadata, crypto_metadata_size,
1943 packet_ptr, nx_crypto_hw_process_callback);
1944 }
1945 else if ((method -> nx_crypto_algorithm >= NX_CRYPTO_ENCRYPTION_AES_CCM_8) &&
1946 (method -> nx_crypto_algorithm <= NX_CRYPTO_ENCRYPTION_AES_CCM))
1947 {
1948
1949 /* AES CCM */
1950 status = _nx_crypto_method_aes_ccm_operation(op, handle, method, key, key_size_in_bits,
1951 input, input_length_in_byte, iv_ptr,
1952 output, output_length_in_byte,
1953 crypto_metadata, crypto_metadata_size,
1954 packet_ptr, nx_crypto_hw_process_callback);
1955
1956 }
1957 else if ((method -> nx_crypto_algorithm >= NX_CRYPTO_ENCRYPTION_AES_GCM_8) &&
1958 (method -> nx_crypto_algorithm <= NX_CRYPTO_ENCRYPTION_AES_GCM_16))
1959 {
1960
1961 /* AES GCM */
1962 status = _nx_crypto_method_aes_gcm_operation(op, handle, method, key, key_size_in_bits,
1963 input, input_length_in_byte, iv_ptr,
1964 output, output_length_in_byte,
1965 crypto_metadata, crypto_metadata_size,
1966 packet_ptr, nx_crypto_hw_process_callback);
1967
1968 }
1969 else if (method -> nx_crypto_algorithm == NX_CRYPTO_ENCRYPTION_AES_CTR)
1970 {
1971
1972 /* AES_CTR */
1973 status = _nx_crypto_method_aes_ctr_operation(op, handle, method, key, key_size_in_bits,
1974 input, input_length_in_byte, iv_ptr,
1975 output, output_length_in_byte,
1976 crypto_metadata, crypto_metadata_size,
1977 packet_ptr, nx_crypto_hw_process_callback);
1978 }
1979 else if (method -> nx_crypto_algorithm == NX_CRYPTO_AUTHENTICATION_AES_XCBC_MAC_96)
1980 {
1981 status = _nx_crypto_method_aes_xcbc_operation(op, handle, method, key, key_size_in_bits,
1982 input, input_length_in_byte, iv_ptr,
1983 output, output_length_in_byte,
1984 crypto_metadata, crypto_metadata_size,
1985 packet_ptr, nx_crypto_hw_process_callback);
1986 }
1987 else
1988 {
1989 status = NX_CRYPTO_INVALID_ALGORITHM;
1990 }
1991
1992 return status;
1993 }
1994
1995 /**************************************************************************/
1996 /* */
1997 /* FUNCTION RELEASE */
1998 /* */
1999 /* _nx_crypto_method_aes_cbc_operation PORTABLE C */
2000 /* 6.3.0 */
2001 /* AUTHOR */
2002 /* */
2003 /* Timothy Stapko, Microsoft Corporation */
2004 /* */
2005 /* DESCRIPTION */
2006 /* */
2007 /* This function encrypts and decrypts a message using */
2008 /* the AES CBC algorithm. */
2009 /* */
2010 /* INPUT */
2011 /* */
2012 /* op AES operation */
2013 /* handle Crypto handle */
2014 /* method Cryption Method Object */
2015 /* key Encryption Key */
2016 /* key_size_in_bits Key size in bits */
2017 /* input Input data */
2018 /* input_length_in_byte Input data size */
2019 /* iv_ptr Initial vector */
2020 /* output Output buffer */
2021 /* output_length_in_byte Output buffer size */
2022 /* crypto_metadata Metadata area */
2023 /* crypto_metadata_size Metadata area size */
2024 /* packet_ptr Pointer to packet */
2025 /* nx_crypto_hw_process_callback Callback function pointer */
2026 /* */
2027 /* OUTPUT */
2028 /* */
2029 /* status Completion status */
2030 /* */
2031 /* CALLS */
2032 /* */
2033 /* _nx_crypto_cbc_encrypt Perform CBC mode encryption */
2034 /* _nx_crypto_cbc_decrypt Perform CBC mode decryption */
2035 /* */
2036 /* CALLED BY */
2037 /* */
2038 /* Application Code */
2039 /* */
2040 /* RELEASE HISTORY */
2041 /* */
2042 /* DATE NAME DESCRIPTION */
2043 /* */
2044 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2045 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2046 /* resulting in version 6.1 */
2047 /* 10-31-2023 Yanwu Cai Modified comment(s), */
2048 /* resulting in version 6.3.0 */
2049 /* */
2050 /**************************************************************************/
_nx_crypto_method_aes_cbc_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2051 NX_CRYPTO_KEEP UINT _nx_crypto_method_aes_cbc_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
2052 VOID *handle, /* Crypto handler */
2053 struct NX_CRYPTO_METHOD_STRUCT *method,
2054 UCHAR *key,
2055 NX_CRYPTO_KEY_SIZE key_size_in_bits,
2056 UCHAR *input,
2057 ULONG input_length_in_byte,
2058 UCHAR *iv_ptr,
2059 UCHAR *output,
2060 ULONG output_length_in_byte,
2061 VOID *crypto_metadata,
2062 ULONG crypto_metadata_size,
2063 VOID *packet_ptr,
2064 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2065 {
2066
2067 NX_CRYPTO_AES *ctx;
2068 UINT status;
2069
2070 NX_CRYPTO_PARAMETER_NOT_USED(handle);
2071 NX_CRYPTO_PARAMETER_NOT_USED(key);
2072 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
2073 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
2074 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
2075 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
2076
2077 NX_CRYPTO_STATE_CHECK
2078
2079 /* Verify the metadata address is 4-byte aligned. */
2080 if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
2081 {
2082 return(NX_CRYPTO_PTR_ERROR);
2083 }
2084
2085 if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
2086 {
2087 return(NX_CRYPTO_PTR_ERROR);
2088 }
2089
2090 ctx = (NX_CRYPTO_AES *)crypto_metadata;
2091
2092 switch (op)
2093 {
2094 case NX_CRYPTO_DECRYPT:
2095 {
2096 status = _nx_crypto_cbc_decrypt_init(&(ctx -> nx_crypto_aes_mode_context.cbc),
2097 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
2098 if (status)
2099 {
2100 break;
2101 }
2102
2103 status = _nx_crypto_cbc_decrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.cbc),
2104 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_decrypt,
2105 input, output, input_length_in_byte,
2106 NX_CRYPTO_AES_BLOCK_SIZE);
2107 } break;
2108
2109 case NX_CRYPTO_ENCRYPT:
2110 {
2111 status = _nx_crypto_cbc_encrypt_init(&(ctx -> nx_crypto_aes_mode_context.cbc),
2112 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
2113 if (status)
2114 {
2115 break;
2116 }
2117
2118 status = _nx_crypto_cbc_encrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.cbc),
2119 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2120 input, output, input_length_in_byte,
2121 NX_CRYPTO_AES_BLOCK_SIZE);
2122 } break;
2123
2124 case NX_CRYPTO_DECRYPT_INITIALIZE:
2125 {
2126 status = _nx_crypto_cbc_decrypt_init(&(ctx -> nx_crypto_aes_mode_context.cbc),
2127 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
2128 } break;
2129
2130 case NX_CRYPTO_ENCRYPT_INITIALIZE:
2131 {
2132 status = _nx_crypto_cbc_encrypt_init(&(ctx -> nx_crypto_aes_mode_context.cbc),
2133 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
2134 } break;
2135
2136 case NX_CRYPTO_DECRYPT_UPDATE:
2137 {
2138 status = _nx_crypto_cbc_decrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.cbc),
2139 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_decrypt,
2140 input, output, input_length_in_byte,
2141 NX_CRYPTO_AES_BLOCK_SIZE);
2142 } break;
2143
2144 case NX_CRYPTO_ENCRYPT_UPDATE:
2145 {
2146 status = _nx_crypto_cbc_encrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.cbc),
2147 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2148 input, output, input_length_in_byte,
2149 NX_CRYPTO_AES_BLOCK_SIZE);
2150 } break;
2151
2152 case NX_CRYPTO_ENCRYPT_CALCULATE:
2153 /* fallthrough */
2154 case NX_CRYPTO_DECRYPT_CALCULATE:
2155 {
2156
2157 /* Nothing to do. */
2158 status = NX_CRYPTO_SUCCESS;
2159 } break;
2160
2161 default:
2162 {
2163 status = NX_CRYPTO_INVALID_ALGORITHM;
2164 } break;
2165 }
2166
2167 return(status);
2168 }
2169
2170 /**************************************************************************/
2171 /* */
2172 /* FUNCTION RELEASE */
2173 /* */
2174 /* _nx_crypto_method_aes_ccm_operation PORTABLE C */
2175 /* 6.3.0 */
2176 /* AUTHOR */
2177 /* */
2178 /* Timothy Stapko, Microsoft Corporation */
2179 /* */
2180 /* DESCRIPTION */
2181 /* */
2182 /* This function encrypts and decrypts a message using */
2183 /* the AES CCM algorithm. */
2184 /* */
2185 /* INPUT */
2186 /* */
2187 /* op AES operation */
2188 /* handle Crypto handle */
2189 /* method Cryption Method Object */
2190 /* key Encryption Key */
2191 /* key_size_in_bits Key size in bits */
2192 /* input Input data */
2193 /* input_length_in_byte Input data size */
2194 /* iv_ptr Initial vector */
2195 /* output Output buffer */
2196 /* output_length_in_byte Output buffer size */
2197 /* crypto_metadata Metadata area */
2198 /* crypto_metadata_size Metadata area size */
2199 /* packet_ptr Pointer to packet */
2200 /* nx_crypto_hw_process_callback Callback function pointer */
2201 /* */
2202 /* OUTPUT */
2203 /* */
2204 /* status Completion status */
2205 /* */
2206 /* CALLS */
2207 /* */
2208 /* _nx_crypto_cbc_encrypt Perform CBC mode encryption */
2209 /* _nx_crypto_cbc_decrypt Perform CBC mode decryption */
2210 /* */
2211 /* CALLED BY */
2212 /* */
2213 /* _nx_crypto_method_aes_operation Handle AES encrypt or decrypt */
2214 /* Application Code */
2215 /* */
2216 /* RELEASE HISTORY */
2217 /* */
2218 /* DATE NAME DESCRIPTION */
2219 /* */
2220 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2221 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2222 /* resulting in version 6.1 */
2223 /* 03-08-2023 Tiejun Zhou Modified comment(s), and */
2224 /* fixed compiler warnings, */
2225 /* resulting in version 6.2.1 */
2226 /* 10-31-2023 Yanwu Cai Modified comment(s), */
2227 /* resulting in version 6.3.0 */
2228 /* */
2229 /**************************************************************************/
_nx_crypto_method_aes_ccm_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2230 NX_CRYPTO_KEEP UINT _nx_crypto_method_aes_ccm_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
2231 VOID *handle, /* Crypto handler */
2232 struct NX_CRYPTO_METHOD_STRUCT *method,
2233 UCHAR *key,
2234 NX_CRYPTO_KEY_SIZE key_size_in_bits,
2235 UCHAR *input,
2236 ULONG input_length_in_byte,
2237 UCHAR *iv_ptr,
2238 UCHAR *output,
2239 ULONG output_length_in_byte,
2240 VOID *crypto_metadata,
2241 ULONG crypto_metadata_size,
2242 VOID *packet_ptr,
2243 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2244 {
2245
2246 NX_CRYPTO_AES *ctx;
2247 UINT status;
2248
2249 NX_CRYPTO_PARAMETER_NOT_USED(handle);
2250 NX_CRYPTO_PARAMETER_NOT_USED(key);
2251 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
2252 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
2253 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
2254 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
2255
2256 NX_CRYPTO_STATE_CHECK
2257
2258 /* Verify the metadata address is 4-byte aligned. */
2259 if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
2260 {
2261 return(NX_CRYPTO_PTR_ERROR);
2262 }
2263
2264 if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
2265 {
2266 return(NX_CRYPTO_PTR_ERROR);
2267 }
2268
2269 ctx = (NX_CRYPTO_AES *)crypto_metadata;
2270
2271 if ((method -> nx_crypto_algorithm < NX_CRYPTO_ENCRYPTION_AES_CCM_8) ||
2272 (method -> nx_crypto_algorithm > NX_CRYPTO_ENCRYPTION_AES_CCM))
2273 {
2274 return(NX_CRYPTO_INVALID_ALGORITHM);
2275 }
2276
2277 /* IV : Nonce length(1 byte) + Nonce
2278 nx_crypto_ICV_size_in_bits: authentication tag length in bits */
2279 switch (op)
2280 {
2281 case NX_CRYPTO_DECRYPT:
2282 {
2283 if (iv_ptr == NX_CRYPTO_NULL ||
2284 (ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len > 0 &&
2285 ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data == NX_CRYPTO_NULL))
2286 {
2287 status = NX_CRYPTO_PTR_ERROR;
2288 break;
2289 }
2290
2291 if (input_length_in_byte < (ULONG)(method -> nx_crypto_ICV_size_in_bits >> 3) ||
2292 output_length_in_byte < input_length_in_byte - (method -> nx_crypto_ICV_size_in_bits >> 3))
2293 {
2294 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2295 break;
2296 }
2297
2298 status = _nx_crypto_ccm_decrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2299 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2300 ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data,
2301 ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len,
2302 input_length_in_byte - (method -> nx_crypto_ICV_size_in_bits >> 3), iv_ptr,
2303 (UCHAR)(method -> nx_crypto_ICV_size_in_bits >> 3),
2304 NX_CRYPTO_AES_BLOCK_SIZE);
2305
2306 if (status)
2307 {
2308 break;
2309 }
2310
2311 status = _nx_crypto_ccm_decrypt_update(NX_CRYPTO_DECRYPT_UPDATE,
2312 ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2313 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2314 input, output, input_length_in_byte - (method -> nx_crypto_ICV_size_in_bits >> 3),
2315 NX_CRYPTO_AES_BLOCK_SIZE);
2316 if (status)
2317 {
2318 break;
2319 }
2320
2321 status = _nx_crypto_ccm_decrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2322 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2323 input + input_length_in_byte - (method -> nx_crypto_ICV_size_in_bits >> 3),
2324 NX_CRYPTO_AES_BLOCK_SIZE);
2325 if (status)
2326 {
2327 break;
2328 }
2329 } break;
2330
2331 case NX_CRYPTO_ENCRYPT:
2332 {
2333 if (iv_ptr == NX_CRYPTO_NULL ||
2334 (ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len > 0 &&
2335 ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data == NX_CRYPTO_NULL))
2336 {
2337 status = NX_CRYPTO_PTR_ERROR;
2338 break;
2339 }
2340
2341 if (output_length_in_byte < input_length_in_byte + (method -> nx_crypto_ICV_size_in_bits >> 3))
2342 {
2343 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2344 break;
2345 }
2346
2347 status = _nx_crypto_ccm_encrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2348 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2349 ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data,
2350 ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len,
2351 input_length_in_byte, iv_ptr,
2352 (UCHAR)(method -> nx_crypto_ICV_size_in_bits >> 3),
2353 NX_CRYPTO_AES_BLOCK_SIZE);
2354
2355 if (status)
2356 {
2357 break;
2358 }
2359
2360 status = _nx_crypto_ccm_encrypt_update(NX_CRYPTO_ENCRYPT_UPDATE,
2361 ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2362 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2363 input, output, input_length_in_byte,
2364 NX_CRYPTO_AES_BLOCK_SIZE);
2365 if (status)
2366 {
2367 break;
2368 }
2369
2370 status = _nx_crypto_ccm_encrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2371 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2372 output + input_length_in_byte,
2373 NX_CRYPTO_AES_BLOCK_SIZE);
2374 if (status)
2375 {
2376 break;
2377 }
2378 } break;
2379
2380 case NX_CRYPTO_SET_ADDITIONAL_DATA:
2381 {
2382
2383 /* Set additonal data pointer. */
2384 ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data = (VOID *)input;
2385
2386 /* Set additional data length. */
2387 ctx -> nx_crypto_aes_mode_context.ccm.nx_crypto_ccm_additional_data_len = input_length_in_byte;
2388
2389 status = NX_CRYPTO_SUCCESS;
2390 } break;
2391
2392 case NX_CRYPTO_DECRYPT_INITIALIZE:
2393 {
2394 if (iv_ptr == NX_CRYPTO_NULL)
2395 {
2396 status = NX_CRYPTO_PTR_ERROR;
2397 break;
2398 }
2399
2400 status = _nx_crypto_ccm_decrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2401 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2402 input, /* pointers to AAD */
2403 input_length_in_byte, /* length of AAD */
2404 output_length_in_byte, /* total length of message */
2405 iv_ptr,
2406 (UCHAR)(method -> nx_crypto_ICV_size_in_bits >> 3),
2407 NX_CRYPTO_AES_BLOCK_SIZE);
2408 } break;
2409
2410 case NX_CRYPTO_DECRYPT_UPDATE:
2411 {
2412 status = _nx_crypto_ccm_decrypt_update(NX_CRYPTO_DECRYPT_UPDATE,
2413 ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2414 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2415 input, output, input_length_in_byte,
2416 NX_CRYPTO_AES_BLOCK_SIZE);
2417
2418 } break;
2419
2420 case NX_CRYPTO_DECRYPT_CALCULATE:
2421 {
2422 status = _nx_crypto_ccm_decrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2423 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2424 input, NX_CRYPTO_AES_BLOCK_SIZE);
2425 } break;
2426
2427 case NX_CRYPTO_ENCRYPT_INITIALIZE:
2428 {
2429 if (iv_ptr == NX_CRYPTO_NULL)
2430 {
2431 status = NX_CRYPTO_PTR_ERROR;
2432 break;
2433 }
2434
2435 status = _nx_crypto_ccm_encrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2436 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2437 input, /* pointers to AAD */
2438 input_length_in_byte, /* length of AAD */
2439 output_length_in_byte, /* total length of message */
2440 iv_ptr,
2441 (UCHAR)(method -> nx_crypto_ICV_size_in_bits >> 3),
2442 NX_CRYPTO_AES_BLOCK_SIZE);
2443 } break;
2444
2445 case NX_CRYPTO_ENCRYPT_UPDATE:
2446 {
2447
2448 status = _nx_crypto_ccm_encrypt_update(NX_CRYPTO_ENCRYPT_UPDATE,
2449 ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2450 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2451 input, output, input_length_in_byte,
2452 NX_CRYPTO_AES_BLOCK_SIZE);
2453 } break;
2454
2455 case NX_CRYPTO_ENCRYPT_CALCULATE:
2456 {
2457
2458 status = _nx_crypto_ccm_encrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.ccm),
2459 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2460 output, NX_CRYPTO_AES_BLOCK_SIZE);
2461 } break;
2462
2463 default:
2464 {
2465 status = NX_CRYPTO_INVALID_ALGORITHM;
2466 } break;
2467 }
2468
2469 return(status);
2470 }
2471
2472 /**************************************************************************/
2473 /* */
2474 /* FUNCTION RELEASE */
2475 /* */
2476 /* _nx_crypto_method_aes_gcm_operation PORTABLE C */
2477 /* 6.3.0 */
2478 /* AUTHOR */
2479 /* */
2480 /* Timothy Stapko, Microsoft Corporation */
2481 /* */
2482 /* DESCRIPTION */
2483 /* */
2484 /* This function encrypts and decrypts a message using */
2485 /* the AES GCM algorithm. */
2486 /* */
2487 /* INPUT */
2488 /* */
2489 /* op AES operation */
2490 /* handle Crypto handle */
2491 /* method Cryption Method Object */
2492 /* key Encryption Key */
2493 /* key_size_in_bits Key size in bits */
2494 /* input Input data */
2495 /* input_length_in_byte Input data size */
2496 /* iv_ptr Initial vector */
2497 /* output Output buffer */
2498 /* output_length_in_byte Output buffer size */
2499 /* crypto_metadata Metadata area */
2500 /* crypto_metadata_size Metadata area size */
2501 /* packet_ptr Pointer to packet */
2502 /* nx_crypto_hw_process_callback Callback function pointer */
2503 /* */
2504 /* OUTPUT */
2505 /* */
2506 /* status Completion status */
2507 /* */
2508 /* CALLS */
2509 /* */
2510 /* _nx_crypto_gcm_operation Perform GCM encryption or */
2511 /* decryption */
2512 /* */
2513 /* CALLED BY */
2514 /* */
2515 /* _nx_crypto_method_aes_operation Handle AES encrypt or decrypt */
2516 /* Application Code */
2517 /* */
2518 /* RELEASE HISTORY */
2519 /* */
2520 /* DATE NAME DESCRIPTION */
2521 /* */
2522 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2523 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2524 /* resulting in version 6.1 */
2525 /* 10-31-2023 Yanwu Cai Modified comment(s), */
2526 /* resulting in version 6.3.0 */
2527 /* */
2528 /**************************************************************************/
_nx_crypto_method_aes_gcm_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2529 NX_CRYPTO_KEEP UINT _nx_crypto_method_aes_gcm_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
2530 VOID *handle, /* Crypto handler */
2531 struct NX_CRYPTO_METHOD_STRUCT *method,
2532 UCHAR *key,
2533 NX_CRYPTO_KEY_SIZE key_size_in_bits,
2534 UCHAR *input,
2535 ULONG input_length_in_byte,
2536 UCHAR *iv_ptr,
2537 UCHAR *output,
2538 ULONG output_length_in_byte,
2539 VOID *crypto_metadata,
2540 ULONG crypto_metadata_size,
2541 VOID *packet_ptr,
2542 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2543 {
2544
2545 NX_CRYPTO_AES *ctx;
2546 UINT icv_len;
2547 UINT message_len;
2548 UINT status;
2549
2550 NX_CRYPTO_PARAMETER_NOT_USED(handle);
2551 NX_CRYPTO_PARAMETER_NOT_USED(key);
2552 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
2553 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
2554 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
2555 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
2556
2557 NX_CRYPTO_STATE_CHECK
2558
2559 /* Verify the metadata address is 4-byte aligned. */
2560 if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
2561 {
2562 return(NX_CRYPTO_PTR_ERROR);
2563 }
2564
2565 if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
2566 {
2567 return(NX_CRYPTO_PTR_ERROR);
2568 }
2569
2570 ctx = (NX_CRYPTO_AES *)crypto_metadata;
2571
2572 if ((method -> nx_crypto_algorithm < NX_CRYPTO_ENCRYPTION_AES_GCM_8) ||
2573 (method -> nx_crypto_algorithm > NX_CRYPTO_ENCRYPTION_AES_GCM_16))
2574 {
2575 return(NX_CRYPTO_INVALID_ALGORITHM);
2576 }
2577
2578 /* IV : Nonce length(1 byte) + Nonce
2579 nx_crypto_ICV_size_in_bits: authentication tag length in bits */
2580 switch (op)
2581 {
2582 case NX_CRYPTO_DECRYPT:
2583 {
2584 if (iv_ptr == NX_CRYPTO_NULL ||
2585 (ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len > 0 &&
2586 ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data == NX_CRYPTO_NULL))
2587 {
2588 status = NX_CRYPTO_PTR_ERROR;
2589 break;
2590 }
2591
2592 icv_len = (method -> nx_crypto_ICV_size_in_bits >> 3);
2593
2594 if (input_length_in_byte < icv_len || output_length_in_byte < input_length_in_byte - icv_len)
2595 {
2596 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2597 break;
2598 }
2599
2600 message_len = input_length_in_byte - icv_len;
2601 status = _nx_crypto_gcm_decrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2602 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2603 ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data,
2604 ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len,
2605 iv_ptr, NX_CRYPTO_AES_BLOCK_SIZE);
2606
2607 if (status)
2608 {
2609 break;
2610 }
2611
2612 status = _nx_crypto_gcm_decrypt_update(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2613 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2614 input, output, message_len,
2615 NX_CRYPTO_AES_BLOCK_SIZE);
2616
2617 if (status)
2618 {
2619 break;
2620 }
2621
2622 status = _nx_crypto_gcm_decrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2623 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2624 input + message_len, icv_len,
2625 NX_CRYPTO_AES_BLOCK_SIZE);
2626 } break;
2627
2628 case NX_CRYPTO_ENCRYPT:
2629 {
2630 if (iv_ptr == NX_CRYPTO_NULL ||
2631 (ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len > 0 &&
2632 ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data == NX_CRYPTO_NULL))
2633 {
2634 status = NX_CRYPTO_PTR_ERROR;
2635 break;
2636 }
2637
2638 icv_len = (method -> nx_crypto_ICV_size_in_bits >> 3);
2639
2640 if (output_length_in_byte < input_length_in_byte + icv_len)
2641 {
2642 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2643 break;
2644 }
2645
2646 status = _nx_crypto_gcm_encrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2647 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2648 ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data,
2649 ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len,
2650 iv_ptr, NX_CRYPTO_AES_BLOCK_SIZE);
2651
2652 if (status)
2653 {
2654 break;
2655 }
2656
2657 status = _nx_crypto_gcm_encrypt_update(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2658 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2659 input, output, input_length_in_byte,
2660 NX_CRYPTO_AES_BLOCK_SIZE);
2661
2662 if (status)
2663 {
2664 break;
2665 }
2666
2667 status = _nx_crypto_gcm_encrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2668 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2669 output + input_length_in_byte, icv_len,
2670 NX_CRYPTO_AES_BLOCK_SIZE);
2671 } break;
2672
2673 case NX_CRYPTO_DECRYPT_INITIALIZE:
2674 {
2675 if (iv_ptr == NX_CRYPTO_NULL)
2676 {
2677 status = NX_CRYPTO_PTR_ERROR;
2678 break;
2679 }
2680
2681 status = _nx_crypto_gcm_decrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2682 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2683 input, /* pointers to AAD */
2684 input_length_in_byte, /* length of AAD */
2685 iv_ptr, NX_CRYPTO_AES_BLOCK_SIZE);
2686 } break;
2687
2688 case NX_CRYPTO_DECRYPT_UPDATE:
2689 {
2690 status = _nx_crypto_gcm_decrypt_update(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2691 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2692 input, output, input_length_in_byte,
2693 NX_CRYPTO_AES_BLOCK_SIZE);
2694 } break;
2695
2696 case NX_CRYPTO_DECRYPT_CALCULATE:
2697 {
2698 icv_len = (method -> nx_crypto_ICV_size_in_bits >> 3);
2699 if (input_length_in_byte < icv_len)
2700 {
2701 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2702 break;
2703 }
2704
2705 status = _nx_crypto_gcm_decrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2706 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2707 input, icv_len,
2708 NX_CRYPTO_AES_BLOCK_SIZE);
2709 } break;
2710
2711 case NX_CRYPTO_ENCRYPT_INITIALIZE:
2712 {
2713 if (iv_ptr == NX_CRYPTO_NULL)
2714 {
2715 status = NX_CRYPTO_PTR_ERROR;
2716 break;
2717 }
2718
2719 status = _nx_crypto_gcm_encrypt_init(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2720 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2721 input, /* pointers to AAD */
2722 input_length_in_byte, /* length of AAD */
2723 iv_ptr, NX_CRYPTO_AES_BLOCK_SIZE);
2724 } break;
2725
2726 case NX_CRYPTO_ENCRYPT_UPDATE:
2727 {
2728 status = _nx_crypto_gcm_encrypt_update(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2729 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2730 input, output, input_length_in_byte,
2731 NX_CRYPTO_AES_BLOCK_SIZE);
2732 } break;
2733
2734 case NX_CRYPTO_ENCRYPT_CALCULATE:
2735 {
2736 icv_len = (method -> nx_crypto_ICV_size_in_bits >> 3);
2737 if (output_length_in_byte < icv_len)
2738 {
2739 status = NX_CRYPTO_INVALID_BUFFER_SIZE;
2740 break;
2741 }
2742
2743 status = _nx_crypto_gcm_encrypt_calculate(ctx, &(ctx -> nx_crypto_aes_mode_context.gcm),
2744 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2745 output, icv_len,
2746 NX_CRYPTO_AES_BLOCK_SIZE);
2747 } break;
2748
2749 case NX_CRYPTO_SET_ADDITIONAL_DATA:
2750 {
2751
2752 /* Set additonal data pointer. */
2753 ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data = (VOID *)input;
2754
2755 /* Set additional data length. */
2756 ctx -> nx_crypto_aes_mode_context.gcm.nx_crypto_gcm_additional_data_len = input_length_in_byte;
2757
2758 status = NX_CRYPTO_SUCCESS;
2759 } break;
2760
2761 default:
2762 {
2763 status = NX_CRYPTO_INVALID_ALGORITHM;
2764 } break;
2765 }
2766
2767 return(status);
2768 }
2769
2770 /**************************************************************************/
2771 /* */
2772 /* FUNCTION RELEASE */
2773 /* */
2774 /* _nx_crypto_method_aes_ctr_operation PORTABLE C */
2775 /* 6.3.0 */
2776 /* AUTHOR */
2777 /* */
2778 /* Timothy Stapko, Microsoft Corporation */
2779 /* */
2780 /* DESCRIPTION */
2781 /* */
2782 /* This function encrypts and decrypts a message using */
2783 /* the AES CTR algorithm. */
2784 /* */
2785 /* INPUT */
2786 /* */
2787 /* op AES operation */
2788 /* handle Crypto handle */
2789 /* method Cryption Method Object */
2790 /* key Encryption Key */
2791 /* key_size_in_bits Key size in bits */
2792 /* input Input data */
2793 /* input_length_in_byte Input data size */
2794 /* iv_ptr Initial vector */
2795 /* output Output buffer */
2796 /* output_length_in_byte Output buffer size */
2797 /* crypto_metadata Metadata area */
2798 /* crypto_metadata_size Metadata area size */
2799 /* packet_ptr Pointer to packet */
2800 /* nx_crypto_hw_process_callback Callback function pointer */
2801 /* */
2802 /* OUTPUT */
2803 /* */
2804 /* status Completion status */
2805 /* */
2806 /* CALLS */
2807 /* */
2808 /* _nx_crypto_ctr_encrypt Perform CTR mode encryption */
2809 /* */
2810 /* CALLED BY */
2811 /* */
2812 /* _nx_crypto_method_aes_operation Handle AES encrypt or decrypt */
2813 /* Application Code */
2814 /* */
2815 /* RELEASE HISTORY */
2816 /* */
2817 /* DATE NAME DESCRIPTION */
2818 /* */
2819 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2820 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2821 /* resulting in version 6.1 */
2822 /* 10-31-2023 Yanwu Cai Modified comment(s), */
2823 /* resulting in version 6.3.0 */
2824 /* */
2825 /**************************************************************************/
_nx_crypto_method_aes_ctr_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2826 NX_CRYPTO_KEEP UINT _nx_crypto_method_aes_ctr_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
2827 VOID *handle, /* Crypto handler */
2828 struct NX_CRYPTO_METHOD_STRUCT *method,
2829 UCHAR *key,
2830 NX_CRYPTO_KEY_SIZE key_size_in_bits,
2831 UCHAR *input,
2832 ULONG input_length_in_byte,
2833 UCHAR *iv_ptr,
2834 UCHAR *output,
2835 ULONG output_length_in_byte,
2836 VOID *crypto_metadata,
2837 ULONG crypto_metadata_size,
2838 VOID *packet_ptr,
2839 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2840 {
2841
2842 NX_CRYPTO_AES *ctx;
2843 UINT status;
2844
2845 NX_CRYPTO_PARAMETER_NOT_USED(op);
2846 NX_CRYPTO_PARAMETER_NOT_USED(handle);
2847 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
2848 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
2849 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
2850
2851 NX_CRYPTO_STATE_CHECK
2852
2853 /* Verify the metadata address is 4-byte aligned. */
2854 if((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
2855 {
2856 return(NX_CRYPTO_PTR_ERROR);
2857 }
2858
2859 if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
2860 {
2861 return(NX_CRYPTO_PTR_ERROR);
2862 }
2863
2864 ctx = (NX_CRYPTO_AES *)crypto_metadata;
2865
2866 switch (op)
2867 {
2868 case NX_CRYPTO_ENCRYPT:
2869 /* fallthrough */
2870 case NX_CRYPTO_DECRYPT:
2871 {
2872 status = _nx_crypto_ctr_encrypt_init(&(ctx -> nx_crypto_aes_mode_context.ctr),
2873 iv_ptr, 8, &key[key_size_in_bits >> 3], 4);
2874 if (status)
2875 {
2876 break;
2877 }
2878
2879 status = _nx_crypto_ctr_encrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.ctr),
2880 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2881 input, output, input_length_in_byte,
2882 NX_CRYPTO_AES_BLOCK_SIZE);
2883 } break;
2884
2885 case NX_CRYPTO_ENCRYPT_INITIALIZE:
2886 /* fallthrough */
2887 case NX_CRYPTO_DECRYPT_INITIALIZE:
2888 {
2889 status = _nx_crypto_ctr_encrypt_init(&(ctx -> nx_crypto_aes_mode_context.ctr),
2890 iv_ptr, 8, input, /* input pointers to nonce */
2891 input_length_in_byte);
2892 } break;
2893
2894 case NX_CRYPTO_ENCRYPT_UPDATE:
2895 /* fallthrough */
2896 case NX_CRYPTO_DECRYPT_UPDATE:
2897 {
2898 status = _nx_crypto_ctr_encrypt(ctx, &(ctx -> nx_crypto_aes_mode_context.ctr),
2899 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
2900 input, output, input_length_in_byte,
2901 NX_CRYPTO_AES_BLOCK_SIZE);
2902 } break;
2903
2904 case NX_CRYPTO_ENCRYPT_CALCULATE:
2905 /* fallthrough */
2906 case NX_CRYPTO_DECRYPT_CALCULATE:
2907 {
2908
2909 /* Nothing to do. */
2910 status = NX_CRYPTO_SUCCESS;
2911 } break;
2912
2913 default:
2914 {
2915 status = NX_CRYPTO_INVALID_ALGORITHM;
2916 } break;
2917 }
2918
2919 return status;
2920 }
2921
2922 /**************************************************************************/
2923 /* */
2924 /* FUNCTION RELEASE */
2925 /* */
2926 /* _nx_crypto_method_aes_xcbc_operation PORTABLE C */
2927 /* 6.3.0 */
2928 /* AUTHOR */
2929 /* */
2930 /* Timothy Stapko, Microsoft Corporation */
2931 /* */
2932 /* DESCRIPTION */
2933 /* */
2934 /* This function encrypts and decrypts a message using */
2935 /* the AES XCBC algorithm. */
2936 /* */
2937 /* INPUT */
2938 /* */
2939 /* op AES operation */
2940 /* handle Crypto handle */
2941 /* method Cryption Method Object */
2942 /* key Encryption Key */
2943 /* key_size_in_bits Key size in bits */
2944 /* input Input data */
2945 /* input_length_in_byte Input data size */
2946 /* iv_ptr Initial vector */
2947 /* output Output buffer */
2948 /* output_length_in_byte Output buffer size */
2949 /* crypto_metadata Metadata area */
2950 /* crypto_metadata_size Metadata area size */
2951 /* packet_ptr Pointer to packet */
2952 /* nx_crypto_hw_process_callback Callback function pointer */
2953 /* */
2954 /* OUTPUT */
2955 /* */
2956 /* status Completion status */
2957 /* */
2958 /* CALLS */
2959 /* */
2960 /* _nx_crypto_xcbc_mac Perform XCBC mode */
2961 /* */
2962 /* CALLED BY */
2963 /* */
2964 /* _nx_crypto_method_aes_operation Handle AES encrypt or decrypt */
2965 /* Application Code */
2966 /* */
2967 /* RELEASE HISTORY */
2968 /* */
2969 /* DATE NAME DESCRIPTION */
2970 /* */
2971 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
2972 /* 09-30-2020 Timothy Stapko Modified comment(s), */
2973 /* resulting in version 6.1 */
2974 /* 10-31-2023 Yanwu Cai Modified comment(s), */
2975 /* resulting in version 6.3.0 */
2976 /* */
2977 /**************************************************************************/
_nx_crypto_method_aes_xcbc_operation(UINT op,VOID * handle,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))2978 NX_CRYPTO_KEEP UINT _nx_crypto_method_aes_xcbc_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
2979 VOID *handle, /* Crypto handler */
2980 struct NX_CRYPTO_METHOD_STRUCT *method,
2981 UCHAR *key,
2982 NX_CRYPTO_KEY_SIZE key_size_in_bits,
2983 UCHAR *input,
2984 ULONG input_length_in_byte,
2985 UCHAR *iv_ptr,
2986 UCHAR *output,
2987 ULONG output_length_in_byte,
2988 VOID *crypto_metadata,
2989 ULONG crypto_metadata_size,
2990 VOID *packet_ptr,
2991 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
2992 {
2993
2994 NX_CRYPTO_AES *ctx;
2995 UINT status;
2996
2997 NX_CRYPTO_PARAMETER_NOT_USED(op);
2998 NX_CRYPTO_PARAMETER_NOT_USED(handle);
2999 NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr);
3000 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
3001 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
3002 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
3003
3004 NX_CRYPTO_STATE_CHECK
3005
3006 /* Verify the metadata address is 4-byte aligned. */
3007 if((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL) || ((((ULONG)crypto_metadata) & 0x3) != 0))
3008 {
3009 return(NX_CRYPTO_PTR_ERROR);
3010 }
3011
3012 if(crypto_metadata_size < sizeof(NX_CRYPTO_AES))
3013 {
3014 return(NX_CRYPTO_PTR_ERROR);
3015 }
3016
3017 ctx = (NX_CRYPTO_AES *)crypto_metadata;
3018
3019 status = _nx_crypto_xcbc_mac(ctx,
3020 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_aes_encrypt,
3021 (UINT (*)(VOID *, UCHAR *, UINT))_nx_crypto_aes_key_set,
3022 key, key_size_in_bits,
3023 input, output, input_length_in_byte,
3024 NX_CRYPTO_NULL, NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS >> 3,
3025 NX_CRYPTO_AES_BLOCK_SIZE);
3026
3027 return status;
3028 }
3029