Merge pull request #25959 from neo1973/TagLib_deprecation_warnings
[xbmc.git] / lib / libUPnP / Neptune / Source / Core / NptCrypto.cpp
blob20b128b932e03bb88cacf983ca9e49f11ddca48e
1 /*****************************************************************
3 | Neptune - Message Digests
5 | Copyright (c) 2002-2010, Axiomatic Systems, LLC.
6 | All rights reserved.
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are met:
10 | * Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 | * Neither the name of Axiomatic Systems nor the
16 | names of its contributors may be used to endorse or promote products
17 | derived from this software without specific prior written permission.
19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 ****************************************************************/
33 Portions of this code are based on the code of LibTomCrypt
34 that was released into public domain by Tom St Denis.
37 /*----------------------------------------------------------------------
38 | includes
39 +---------------------------------------------------------------------*/
40 #include "NptCrypto.h"
41 #include "NptUtils.h"
42 #include "NptTypes.h"
44 /*----------------------------------------------------------------------
45 | constants
46 +---------------------------------------------------------------------*/
47 #define NPT_AES_BLOCK_SIZE 16
49 static const NPT_UInt32 TE0[256] = {
50 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
51 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
52 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
53 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
54 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL,
55 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL,
56 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL,
57 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL,
58 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL,
59 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL,
60 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL,
61 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL,
62 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL,
63 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL,
64 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL,
65 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL,
66 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL,
67 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL,
68 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL,
69 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL,
70 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL,
71 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL,
72 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL,
73 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL,
74 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL,
75 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL,
76 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL,
77 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL,
78 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL,
79 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL,
80 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL,
81 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL,
82 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL,
83 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL,
84 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL,
85 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL,
86 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL,
87 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL,
88 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL,
89 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL,
90 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL,
91 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL,
92 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL,
93 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL,
94 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL,
95 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL,
96 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL,
97 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL,
98 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL,
99 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL,
100 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL,
101 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL,
102 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL,
103 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL,
104 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL,
105 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL,
106 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL,
107 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL,
108 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL,
109 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL,
110 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL,
111 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL,
112 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL,
113 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL,
116 static const NPT_UInt32 Te4[256] = {
117 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL,
118 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL,
119 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL,
120 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL,
121 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL,
122 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL,
123 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL,
124 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL,
125 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL,
126 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL,
127 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL,
128 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL,
129 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL,
130 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL,
131 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL,
132 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL,
133 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL,
134 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL,
135 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL,
136 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL,
137 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL,
138 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL,
139 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL,
140 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL,
141 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL,
142 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL,
143 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL,
144 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL,
145 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL,
146 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL,
147 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL,
148 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL,
149 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL,
150 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL,
151 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL,
152 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL,
153 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL,
154 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL,
155 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL,
156 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL,
157 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL,
158 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL,
159 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL,
160 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL,
161 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL,
162 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL,
163 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL,
164 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL,
165 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL,
166 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL,
167 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL,
168 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL,
169 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL,
170 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL,
171 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL,
172 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL,
173 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL,
174 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL,
175 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL,
176 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL,
177 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL,
178 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL,
179 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL,
180 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL,
183 static const NPT_UInt32 TD0[256] = {
184 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
185 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
186 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL,
187 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL,
188 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL,
189 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL,
190 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL,
191 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL,
192 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL,
193 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL,
194 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL,
195 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL,
196 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL,
197 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL,
198 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL,
199 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL,
200 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL,
201 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL,
202 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL,
203 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL,
204 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL,
205 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL,
206 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL,
207 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL,
208 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL,
209 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL,
210 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL,
211 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL,
212 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL,
213 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL,
214 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL,
215 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL,
216 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL,
217 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL,
218 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL,
219 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL,
220 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL,
221 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL,
222 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL,
223 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL,
224 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL,
225 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL,
226 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL,
227 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL,
228 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL,
229 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL,
230 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL,
231 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL,
232 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL,
233 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL,
234 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL,
235 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL,
236 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL,
237 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL,
238 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL,
239 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL,
240 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL,
241 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL,
242 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL,
243 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL,
244 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL,
245 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL,
246 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL,
247 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL,
250 static const NPT_UInt32 Td4[256] = {
251 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL,
252 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL,
253 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL,
254 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL,
255 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL,
256 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL,
257 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL,
258 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL,
259 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL,
260 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL,
261 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL,
262 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL,
263 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL,
264 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL,
265 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL,
266 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL,
267 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL,
268 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL,
269 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL,
270 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL,
271 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL,
272 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL,
273 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL,
274 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL,
275 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL,
276 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL,
277 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL,
278 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL,
279 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL,
280 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL,
281 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL,
282 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL,
283 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL,
284 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL,
285 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL,
286 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL,
287 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL,
288 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL,
289 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL,
290 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL,
291 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL,
292 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL,
293 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL,
294 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL,
295 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL,
296 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL,
297 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL,
298 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL,
299 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL,
300 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL,
301 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL,
302 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL,
303 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL,
304 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL,
305 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL,
306 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL,
307 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL,
308 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL,
309 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL,
310 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL,
311 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL,
312 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL,
313 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL,
314 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL,
317 static const NPT_UInt32 rcon[] = {
318 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL,
319 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL,
320 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
323 /*----------------------------------------------------------------------
324 | macros
325 +---------------------------------------------------------------------*/
326 #define RORc(x, y) \
327 ( ((((NPT_UInt32)(x)&0xFFFFFFFFUL)>>(NPT_UInt32)(y)) | \
328 ((NPT_UInt32)(x)<<(NPT_UInt32)(32-(y)))) & 0xFFFFFFFFUL)
330 #define Te0(x) TE0[x]
331 #define Te1(x) RORc(TE0[x], 8)
332 #define Te2(x) RORc(TE0[x], 16)
333 #define Te3(x) RORc(TE0[x], 24)
335 #define Td0(x) TD0[x]
336 #define Td1(x) RORc(TD0[x], 8)
337 #define Td2(x) RORc(TD0[x], 16)
338 #define Td3(x) RORc(TD0[x], 24)
340 #define Te4_0 0x000000FF & Te4
341 #define Te4_1 0x0000FF00 & Te4
342 #define Te4_2 0x00FF0000 & Te4
343 #define Te4_3 0xFF000000 & Te4
345 #define NPT_BYTE(x,n) (((unsigned char)((x) >> (8 * (n)))))
347 /*----------------------------------------------------------------------
348 | local utility functions
349 +---------------------------------------------------------------------*/
350 static NPT_UInt32 setup_mix(NPT_UInt32 temp)
352 return (Te4_3[NPT_BYTE(temp, 2)]) ^
353 (Te4_2[NPT_BYTE(temp, 1)]) ^
354 (Te4_1[NPT_BYTE(temp, 0)]) ^
355 (Te4_0[NPT_BYTE(temp, 3)]);
358 static NPT_UInt32 setup_mix2(NPT_UInt32 temp)
360 return Td0(0xFF & Te4[NPT_BYTE(temp, 3)]) ^
361 Td1(0xFF & Te4[NPT_BYTE(temp, 2)]) ^
362 Td2(0xFF & Te4[NPT_BYTE(temp, 1)]) ^
363 Td3(0xFF & Te4[NPT_BYTE(temp, 0)]);
366 static inline NPT_UInt32 LOAD32H(const NPT_UInt8* p)
368 return ((((NPT_UInt32)p[0])<<24) |
369 (((NPT_UInt32)p[1])<<16) |
370 (((NPT_UInt32)p[2])<< 8) |
371 (((NPT_UInt32)p[3]) ));
374 static inline void STORE32H(NPT_UInt32 x, NPT_UInt8* p)
376 p[0] = (NPT_UInt8)(x>>24);
377 p[1] = (NPT_UInt8)(x>>16);
378 p[2] = (NPT_UInt8)(x>> 8);
379 p[3] = (NPT_UInt8)(x );
382 /*----------------------------------------------------------------------
383 | NPT_AesBlockCipher
384 +---------------------------------------------------------------------*/
385 class NPT_AesBlockCipher : public NPT_BlockCipher
387 public:
388 NPT_AesBlockCipher(const NPT_UInt8* key,
389 NPT_Size key_size);
390 NPT_Result ProcessBlock(const NPT_UInt8* , NPT_UInt8*) {
391 return NPT_ERROR_INTERNAL;
393 NPT_Size GetBlockSize() { return NPT_AES_BLOCK_SIZE; }
394 Algorithm GetAlgorithm() { return AES_128; }
396 protected:
397 NPT_UInt32 m_eK[60];
398 NPT_UInt32 m_dK[60];
399 NPT_Cardinal m_RoundCount;
402 /*----------------------------------------------------------------------
403 | NPT_AesBlockEncrypter
404 +---------------------------------------------------------------------*/
405 class NPT_AesBlockEncrypter : public NPT_AesBlockCipher {
406 public:
407 NPT_AesBlockEncrypter(const NPT_UInt8* key, NPT_Size key_size) :
408 NPT_AesBlockCipher(key, key_size) {}
409 Direction GetDirection() { return ENCRYPT; }
410 NPT_Result ProcessBlock(const NPT_UInt8* block_in, NPT_UInt8* block_out);
413 /*----------------------------------------------------------------------
414 | NPT_AesBlockDecrypter
415 +---------------------------------------------------------------------*/
416 class NPT_AesBlockDecrypter : public NPT_AesBlockCipher {
417 public:
418 NPT_AesBlockDecrypter(const NPT_UInt8* key, NPT_Size key_size) :
419 NPT_AesBlockCipher(key, key_size) {}
420 Direction GetDirection() { return DECRYPT; }
421 NPT_Result ProcessBlock(const NPT_UInt8* block_in, NPT_UInt8* block_out);
424 /*----------------------------------------------------------------------
425 | NPT_AesBlockCipher::NPT_AesBlockCipher
426 +---------------------------------------------------------------------*/
427 NPT_AesBlockCipher::NPT_AesBlockCipher(const NPT_UInt8* key,
428 NPT_Size key_size)
430 unsigned int i, j;
431 NPT_UInt32 temp;
432 NPT_UInt32 *rrk;
434 m_RoundCount = 10 + ((key_size/8)-2)*2;
436 /* setup the forward key */
437 i = 0;
438 NPT_UInt32* rk = m_eK;
439 rk[0] = LOAD32H(key );
440 rk[1] = LOAD32H(key + 4);
441 rk[2] = LOAD32H(key + 8);
442 rk[3] = LOAD32H(key + 12);
443 if (key_size == 16) {
444 j = 44;
445 for (;;) {
446 temp = rk[3];
447 rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
448 rk[5] = rk[1] ^ rk[4];
449 rk[6] = rk[2] ^ rk[5];
450 rk[7] = rk[3] ^ rk[6];
451 if (++i == 10) {
452 break;
454 rk += 4;
456 } else if (key_size == 24) {
457 j = 52;
458 rk[4] = LOAD32H(key + 16);
459 rk[5] = LOAD32H(key + 20);
460 for (;;) {
461 #ifdef _MSC_VER
462 temp = m_eK[rk - m_eK + 5];
463 #else
464 temp = rk[5];
465 #endif
466 rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
467 rk[ 7] = rk[ 1] ^ rk[ 6];
468 rk[ 8] = rk[ 2] ^ rk[ 7];
469 rk[ 9] = rk[ 3] ^ rk[ 8];
470 if (++i == 8) {
471 break;
473 rk[10] = rk[ 4] ^ rk[ 9];
474 rk[11] = rk[ 5] ^ rk[10];
475 rk += 6;
477 } else if (key_size == 32) {
478 j = 60;
479 rk[4] = LOAD32H(key + 16);
480 rk[5] = LOAD32H(key + 20);
481 rk[6] = LOAD32H(key + 24);
482 rk[7] = LOAD32H(key + 28);
483 for (;;) {
484 temp = rk[7];
485 rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
486 rk[ 9] = rk[ 1] ^ rk[ 8];
487 rk[10] = rk[ 2] ^ rk[ 9];
488 rk[11] = rk[ 3] ^ rk[10];
489 if (++i == 7) {
490 break;
492 temp = rk[11];
493 rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8));
494 rk[13] = rk[ 5] ^ rk[12];
495 rk[14] = rk[ 6] ^ rk[13];
496 rk[15] = rk[ 7] ^ rk[14];
497 rk += 8;
499 } else {
500 /* this can't happen */
501 return;
504 /* setup the inverse key now */
505 rk = m_dK;
506 rrk = m_eK + j - 4;
508 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
509 /* copy first */
510 *rk++ = *rrk++;
511 *rk++ = *rrk++;
512 *rk++ = *rrk++;
513 *rk = *rrk;
514 rk -= 3; rrk -= 3;
516 for (i = 1; i < m_RoundCount; i++) {
517 rrk -= 4;
518 rk += 4;
519 temp = rrk[0];
520 rk[0] = setup_mix2(temp);
521 temp = rrk[1];
522 rk[1] = setup_mix2(temp);
523 temp = rrk[2];
524 rk[2] = setup_mix2(temp);
525 temp = rrk[3];
526 rk[3] = setup_mix2(temp);
529 /* copy last */
530 rrk -= 4;
531 rk += 4;
532 *rk++ = *rrk++;
533 *rk++ = *rrk++;
534 *rk++ = *rrk++;
535 *rk = *rrk;
538 /*----------------------------------------------------------------------
539 | NPT_AesBlockEncrypter::ProcessBlock
540 +---------------------------------------------------------------------*/
541 NPT_Result
542 NPT_AesBlockEncrypter::ProcessBlock(const NPT_UInt8* pt, NPT_UInt8* ct)
544 NPT_UInt32 s0, s1, s2, s3, t0, t1, t2, t3;
545 int Nr = m_RoundCount;
546 NPT_UInt32* rk = m_eK;
549 * map byte array block to cipher state
550 * and add initial round key:
552 s0 = LOAD32H(pt ); s0 ^= rk[0];
553 s1 = LOAD32H(pt + 4); s1 ^= rk[1];
554 s2 = LOAD32H(pt + 8); s2 ^= rk[2];
555 s3 = LOAD32H(pt + 12); s3 ^= rk[3];
557 for (int r = 0; ; r++) {
558 rk += 4;
559 t0 =
560 Te0(NPT_BYTE(s0, 3)) ^
561 Te1(NPT_BYTE(s1, 2)) ^
562 Te2(NPT_BYTE(s2, 1)) ^
563 Te3(NPT_BYTE(s3, 0)) ^
564 rk[0];
565 t1 =
566 Te0(NPT_BYTE(s1, 3)) ^
567 Te1(NPT_BYTE(s2, 2)) ^
568 Te2(NPT_BYTE(s3, 1)) ^
569 Te3(NPT_BYTE(s0, 0)) ^
570 rk[1];
571 t2 =
572 Te0(NPT_BYTE(s2, 3)) ^
573 Te1(NPT_BYTE(s3, 2)) ^
574 Te2(NPT_BYTE(s0, 1)) ^
575 Te3(NPT_BYTE(s1, 0)) ^
576 rk[2];
577 t3 =
578 Te0(NPT_BYTE(s3, 3)) ^
579 Te1(NPT_BYTE(s0, 2)) ^
580 Te2(NPT_BYTE(s1, 1)) ^
581 Te3(NPT_BYTE(s2, 0)) ^
582 rk[3];
583 if (r == Nr-2) {
584 break;
586 s0 = t0; s1 = t1; s2 = t2; s3 = t3;
588 rk += 4;
591 * apply last round and
592 * map cipher state to byte array block:
594 s0 =
595 (Te4_3[NPT_BYTE(t0, 3)]) ^
596 (Te4_2[NPT_BYTE(t1, 2)]) ^
597 (Te4_1[NPT_BYTE(t2, 1)]) ^
598 (Te4_0[NPT_BYTE(t3, 0)]) ^
599 rk[0];
600 STORE32H(s0, ct);
601 s1 =
602 (Te4_3[NPT_BYTE(t1, 3)]) ^
603 (Te4_2[NPT_BYTE(t2, 2)]) ^
604 (Te4_1[NPT_BYTE(t3, 1)]) ^
605 (Te4_0[NPT_BYTE(t0, 0)]) ^
606 rk[1];
607 STORE32H(s1, ct+4);
608 s2 =
609 (Te4_3[NPT_BYTE(t2, 3)]) ^
610 (Te4_2[NPT_BYTE(t3, 2)]) ^
611 (Te4_1[NPT_BYTE(t0, 1)]) ^
612 (Te4_0[NPT_BYTE(t1, 0)]) ^
613 rk[2];
614 STORE32H(s2, ct+8);
615 s3 =
616 (Te4_3[NPT_BYTE(t3, 3)]) ^
617 (Te4_2[NPT_BYTE(t0, 2)]) ^
618 (Te4_1[NPT_BYTE(t1, 1)]) ^
619 (Te4_0[NPT_BYTE(t2, 0)]) ^
620 rk[3];
621 STORE32H(s3, ct+12);
623 return NPT_SUCCESS;
626 /*----------------------------------------------------------------------
627 | NPT_AesBlockDecrypter::ProcessBlock
628 +---------------------------------------------------------------------*/
629 NPT_Result
630 NPT_AesBlockDecrypter::ProcessBlock(const NPT_UInt8* ct, NPT_UInt8* pt)
632 NPT_UInt32 s0, s1, s2, s3, t0, t1, t2, t3;
634 int Nr = m_RoundCount;
635 NPT_UInt32* rk = m_dK;
638 * map byte array block to cipher state
639 * and add initial round key:
641 s0 = LOAD32H(ct ); s0 ^= rk[0];
642 s1 = LOAD32H(ct + 4); s1 ^= rk[1];
643 s2 = LOAD32H(ct + 8); s2 ^= rk[2];
644 s3 = LOAD32H(ct + 12); s3 ^= rk[3];
646 for (int r = 0; ; r++) {
647 rk += 4;
648 t0 =
649 Td0(NPT_BYTE(s0, 3)) ^
650 Td1(NPT_BYTE(s3, 2)) ^
651 Td2(NPT_BYTE(s2, 1)) ^
652 Td3(NPT_BYTE(s1, 0)) ^
653 rk[0];
654 t1 =
655 Td0(NPT_BYTE(s1, 3)) ^
656 Td1(NPT_BYTE(s0, 2)) ^
657 Td2(NPT_BYTE(s3, 1)) ^
658 Td3(NPT_BYTE(s2, 0)) ^
659 rk[1];
660 t2 =
661 Td0(NPT_BYTE(s2, 3)) ^
662 Td1(NPT_BYTE(s1, 2)) ^
663 Td2(NPT_BYTE(s0, 1)) ^
664 Td3(NPT_BYTE(s3, 0)) ^
665 rk[2];
666 t3 =
667 Td0(NPT_BYTE(s3, 3)) ^
668 Td1(NPT_BYTE(s2, 2)) ^
669 Td2(NPT_BYTE(s1, 1)) ^
670 Td3(NPT_BYTE(s0, 0)) ^
671 rk[3];
672 if (r == Nr-2) {
673 break;
675 s0 = t0; s1 = t1; s2 = t2; s3 = t3;
677 rk += 4;
680 * apply last round and
681 * map cipher state to byte array block:
683 s0 =
684 (Td4[NPT_BYTE(t0, 3)] & 0xff000000) ^
685 (Td4[NPT_BYTE(t3, 2)] & 0x00ff0000) ^
686 (Td4[NPT_BYTE(t2, 1)] & 0x0000ff00) ^
687 (Td4[NPT_BYTE(t1, 0)] & 0x000000ff) ^
688 rk[0];
689 STORE32H(s0, pt);
690 s1 =
691 (Td4[NPT_BYTE(t1, 3)] & 0xff000000) ^
692 (Td4[NPT_BYTE(t0, 2)] & 0x00ff0000) ^
693 (Td4[NPT_BYTE(t3, 1)] & 0x0000ff00) ^
694 (Td4[NPT_BYTE(t2, 0)] & 0x000000ff) ^
695 rk[1];
696 STORE32H(s1, pt+4);
697 s2 =
698 (Td4[NPT_BYTE(t2, 3)] & 0xff000000) ^
699 (Td4[NPT_BYTE(t1, 2)] & 0x00ff0000) ^
700 (Td4[NPT_BYTE(t0, 1)] & 0x0000ff00) ^
701 (Td4[NPT_BYTE(t3, 0)] & 0x000000ff) ^
702 rk[2];
703 STORE32H(s2, pt+8);
704 s3 =
705 (Td4[NPT_BYTE(t3, 3)] & 0xff000000) ^
706 (Td4[NPT_BYTE(t2, 2)] & 0x00ff0000) ^
707 (Td4[NPT_BYTE(t1, 1)] & 0x0000ff00) ^
708 (Td4[NPT_BYTE(t0, 0)] & 0x000000ff) ^
709 rk[3];
710 STORE32H(s3, pt+12);
712 return NPT_SUCCESS;
715 /*----------------------------------------------------------------------
716 | NPT_BlockCipher::Create
717 +---------------------------------------------------------------------*/
718 NPT_Result
719 NPT_BlockCipher::Create(Algorithm algorithm,
720 Direction direction,
721 const NPT_UInt8* key,
722 NPT_Size key_size,
723 NPT_BlockCipher*& cipher)
725 cipher = NULL;
726 switch (algorithm) {
727 case AES_128:
728 if (key == NULL || key_size != 16) return NPT_ERROR_INVALID_PARAMETERS;
729 switch (direction) {
730 case ENCRYPT:
731 cipher = new NPT_AesBlockEncrypter(key, 16);
732 return NPT_SUCCESS;
734 case DECRYPT:
735 cipher = new NPT_AesBlockDecrypter(key, 16);
736 return NPT_SUCCESS;
738 default:
739 return NPT_ERROR_INVALID_PARAMETERS;
741 default:
742 return NPT_ERROR_NOT_SUPPORTED;
746 /*----------------------------------------------------------------------
747 | NPT_BlockCipher::ProcessCbc
748 +---------------------------------------------------------------------*/
749 NPT_Result
750 NPT_BlockCipher::ProcessCbc(const NPT_UInt8* input, NPT_Size input_size, const NPT_UInt8* iv, NPT_DataBuffer& output)
752 // this version only supports block sizes of 16
753 if (GetBlockSize() != 16) return NPT_ERROR_NOT_SUPPORTED;
755 // decrypt or encrypt depending on the direction of the cipher
756 NPT_UInt8 chain[16];
757 if (iv) {
758 NPT_CopyMemory(chain, iv, 16);
759 } else {
760 NPT_SetMemory(chain, 0, 16);
762 if (GetDirection() == ENCRYPT) {
763 // pad
764 unsigned int padding_size = 16-(input_size%16);
765 NPT_DataBuffer padded_input;
766 padded_input.SetDataSize(input_size+padding_size);
767 NPT_UInt8* plaintext = padded_input.UseData();
768 NPT_CopyMemory(plaintext, input, input_size);
769 for (unsigned int x=0; x<padding_size; x++) {
770 plaintext[input_size+x] = padding_size;
773 // process all blocks
774 unsigned int block_count = (input_size+padding_size)/16;
775 output.SetDataSize(block_count*16);
776 NPT_UInt8* ciphertext = output.UseData();
777 for (unsigned int x=0; x<block_count; x++) {
778 // xor with the chaining block
779 for (unsigned int y=0; y<16; y++) {
780 plaintext[y] ^= chain[y];
783 // encrypt the block
784 NPT_Result result = ProcessBlock(plaintext, ciphertext);
785 if (NPT_FAILED(result)) return result;
787 // chain and move forward to the next block
788 NPT_CopyMemory(chain, ciphertext, 16);
789 plaintext += 16;
790 ciphertext += 16;
792 } else {
793 // check that we have an integral number of blocks
794 if (input_size%16) return NPT_ERROR_INVALID_PARAMETERS;
796 // process all blocks
797 unsigned int block_count = input_size/16;
798 output.SetBufferSize(block_count*16);
799 NPT_UInt8* plaintext = output.UseData();
800 const NPT_UInt8* ciphertext = input;
801 for (unsigned int x=0; x<block_count; x++) {
802 // decrypt block
803 NPT_Result result = ProcessBlock(ciphertext, plaintext);
804 if (NPT_FAILED(result)) return result;
806 // xor with the chaining block
807 for (unsigned int y=0; y<16; y++) {
808 plaintext[y] ^= chain[y];
811 // chain and move forward to the next block
812 NPT_CopyMemory(chain, ciphertext, 16);
813 plaintext += 16;
814 ciphertext += 16;
817 // padding
818 plaintext -= 16;
819 unsigned int padding_size = plaintext[15];
820 if (padding_size == 0 || padding_size > 16) {
821 return NPT_ERROR_INVALID_FORMAT;
823 for (unsigned int y=0; y<padding_size; y++) {
824 if (plaintext[15-y] != padding_size) {
825 return NPT_ERROR_INVALID_FORMAT;
828 output.SetDataSize(block_count*16 - padding_size);
831 return NPT_SUCCESS;