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