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