#
source:
trunk/third/gnome-keyring/aes.c
@
21094

Revision 21094, 8.0 KB checked in by ghudson, 20 years ago (diff) |
---|

Line | |
---|---|

1 | /* |

2 | * Copyright (c) 2002, 2003 Bob Deblier |

3 | * |

4 | * This library is free software; you can redistribute it and/or |

5 | * modify it under the terms of the GNU Lesser General Public |

6 | * License as published by the Free Software Foundation; either |

7 | * version 2.1 of the License, or (at your option) any later version. |

8 | * |

9 | * This library is distributed in the hope that it will be useful, |

10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |

11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |

12 | * Lesser General Public License for more details. |

13 | * |

14 | * You should have received a copy of the GNU Lesser General Public |

15 | * License along with this library; if not, write to the Free Software |

16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |

17 | * |

18 | */ |

19 | |

20 | /*!\file aes.c |

21 | * \brief AES block cipher, as specified by NIST FIPS 197. |

22 | * |

23 | * The table lookup method was inspired by Brian Gladman's AES implementation, |

24 | * which is much more readable than the standard code. |

25 | * |

26 | * \author Bob Deblier <bob.deblier@pandora.be> |

27 | * \ingroup BC_aes_m BC_m |

28 | */ |

29 | |

30 | /* Modified from beecrypt by alexander larsson <alexl@redhat.com> */ |

31 | |

32 | #include "config.h" |

33 | |

34 | #include "aes.h" |

35 | |

36 | #if defined(G_BYTE_ORDER) && defined(G_BIG_ENDIAN) && defined(G_LITTLE_ENDIAN) |

37 | # if (G_BYTE_ORDER != G_BIG_ENDIAN) && (G_BYTE_ORDER != G_LITTLE_ENDIAN) |

38 | # error unsupported endian-ness. |

39 | # endif |

40 | #endif |

41 | |

42 | #if WORDS_BIGENDIAN |

43 | # include "aes_be.h" |

44 | #else |

45 | # include "aes_le.h" |

46 | #endif |

47 | |

48 | int aesSetup(aesParam* ap, const byte* key, size_t keybits, cipherOperation op) |

49 | { |

50 | if ((op != ENCRYPT) && (op != DECRYPT)) |

51 | return -1; |

52 | |

53 | if (((keybits & 63) == 0) && (keybits >= 128) && (keybits <= 256)) |

54 | { |

55 | register guint32* rk, t, i, j; |

56 | |

57 | /* clear fdback/iv */ |

58 | ap->fdback[0] = 0; |

59 | ap->fdback[1] = 0; |

60 | ap->fdback[2] = 0; |

61 | ap->fdback[3] = 0; |

62 | |

63 | ap->nr = 6 + (keybits >> 5); |

64 | |

65 | rk = ap->k; |

66 | |

67 | memcpy(rk, key, keybits >> 3); |

68 | |

69 | i = 0; |

70 | |

71 | if (keybits == 128) |

72 | { |

73 | while (1) |

74 | { |

75 | t = rk[3]; |

76 | #if WORDS_BIGENDIAN |

77 | t = (_ae4[(t >> 16) & 0xff] & 0xff000000) ^ |

78 | (_ae4[(t >> 8) & 0xff] & 0x00ff0000) ^ |

79 | (_ae4[(t ) & 0xff] & 0x0000ff00) ^ |

80 | (_ae4[(t >> 24) ] & 0x000000ff) ^ |

81 | _arc[i]; |

82 | #else |

83 | t = (_ae4[(t >> 8) & 0xff] & 0x000000ff) ^ |

84 | (_ae4[(t >> 16) & 0xff] & 0x0000ff00) ^ |

85 | (_ae4[(t >> 24) ] & 0x00ff0000) ^ |

86 | (_ae4[(t ) & 0xff] & 0xff000000) ^ |

87 | _arc[i]; |

88 | #endif |

89 | rk[4] = (t ^= rk[0]); |

90 | rk[5] = (t ^= rk[1]); |

91 | rk[6] = (t ^= rk[2]); |

92 | rk[7] = (t ^= rk[3]); |

93 | if (++i == 10) |

94 | break; |

95 | rk += 4; |

96 | } |

97 | } |

98 | else if (keybits == 192) |

99 | { |

100 | while (1) |

101 | { |

102 | t = rk[5]; |

103 | #if WORDS_BIGENDIAN |

104 | t = (_ae4[(t >> 16) & 0xff] & 0xff000000) ^ |

105 | (_ae4[(t >> 8) & 0xff] & 0x00ff0000) ^ |

106 | (_ae4[(t ) & 0xff] & 0x0000ff00) ^ |

107 | (_ae4[(t >> 24) ] & 0x000000ff) ^ |

108 | _arc[i]; |

109 | #else |

110 | t = (_ae4[(t >> 8) & 0xff] & 0x000000ff) ^ |

111 | (_ae4[(t >> 16) & 0xff] & 0x0000ff00) ^ |

112 | (_ae4[(t >> 24) ] & 0x00ff0000) ^ |

113 | (_ae4[(t ) & 0xff] & 0xff000000) ^ |

114 | _arc[i]; |

115 | #endif |

116 | rk[6] = (t ^= rk[0]); |

117 | rk[7] = (t ^= rk[1]); |

118 | rk[8] = (t ^= rk[2]); |

119 | rk[9] = (t ^= rk[3]); |

120 | if (++i == 8) |

121 | break; |

122 | rk[10] = (t ^= rk[4]); |

123 | rk[11] = (t ^= rk[5]); |

124 | rk += 6; |

125 | } |

126 | } |

127 | else if (keybits == 256) |

128 | { |

129 | while (1) |

130 | { |

131 | t = rk[7]; |

132 | #if WORDS_BIGENDIAN |

133 | t = (_ae4[(t >> 16) & 0xff] & 0xff000000) ^ |

134 | (_ae4[(t >> 8) & 0xff] & 0x00ff0000) ^ |

135 | (_ae4[(t ) & 0xff] & 0x0000ff00) ^ |

136 | (_ae4[(t >> 24) ] & 0x000000ff) ^ |

137 | _arc[i]; |

138 | #else |

139 | t = (_ae4[(t >> 8) & 0xff] & 0x000000ff) ^ |

140 | (_ae4[(t >> 16) & 0xff] & 0x0000ff00) ^ |

141 | (_ae4[(t >> 24) ] & 0x00ff0000) ^ |

142 | (_ae4[(t ) & 0xff] & 0xff000000) ^ |

143 | _arc[i]; |

144 | #endif |

145 | rk[8] = (t ^= rk[0]); |

146 | rk[9] = (t ^= rk[1]); |

147 | rk[10] = (t ^= rk[2]); |

148 | rk[11] = (t ^= rk[3]); |

149 | if (++i == 7) |

150 | break; |

151 | #if WORDS_BIGENDIAN |

152 | t = (_ae4[(t >> 24) ] & 0xff000000) ^ |

153 | (_ae4[(t >> 16) & 0xff] & 0x00ff0000) ^ |

154 | (_ae4[(t >> 8) & 0xff] & 0x0000ff00) ^ |

155 | (_ae4[(t ) & 0xff] & 0x000000ff); |

156 | #else |

157 | t = (_ae4[(t ) & 0xff] & 0x000000ff) ^ |

158 | (_ae4[(t >> 8) & 0xff] & 0x0000ff00) ^ |

159 | (_ae4[(t >> 16) & 0xff] & 0x00ff0000) ^ |

160 | (_ae4[(t >> 24) ] & 0xff000000); |

161 | #endif |

162 | rk[12] = (t ^= rk[4]); |

163 | rk[13] = (t ^= rk[5]); |

164 | rk[14] = (t ^= rk[6]); |

165 | rk[15] = (t ^= rk[7]); |

166 | rk += 8; |

167 | } |

168 | } |

169 | |

170 | if (op == DECRYPT) |

171 | { |

172 | rk = ap->k; |

173 | |

174 | for (i = 0, j = (ap->nr << 2); i < j; i += 4, j -= 4) |

175 | { |

176 | t = rk[i ]; rk[i ] = rk[j ]; rk[j ] = t; |

177 | t = rk[i+1]; rk[i+1] = rk[j+1]; rk[j+1] = t; |

178 | t = rk[i+2]; rk[i+2] = rk[j+2]; rk[j+2] = t; |

179 | t = rk[i+3]; rk[i+3] = rk[j+3]; rk[j+3] = t; |

180 | } |

181 | for (i = 1; i < ap->nr; i++) |

182 | { |

183 | rk += 4; |

184 | #if WORDS_BIGENDIAN |

185 | rk[0] = |

186 | _ad0[_ae4[(rk[0] >> 24) ] & 0xff] ^ |

187 | _ad1[_ae4[(rk[0] >> 16) & 0xff] & 0xff] ^ |

188 | _ad2[_ae4[(rk[0] >> 8) & 0xff] & 0xff] ^ |

189 | _ad3[_ae4[(rk[0] ) & 0xff] & 0xff]; |

190 | rk[1] = |

191 | _ad0[_ae4[(rk[1] >> 24) ] & 0xff] ^ |

192 | _ad1[_ae4[(rk[1] >> 16) & 0xff] & 0xff] ^ |

193 | _ad2[_ae4[(rk[1] >> 8) & 0xff] & 0xff] ^ |

194 | _ad3[_ae4[(rk[1] ) & 0xff] & 0xff]; |

195 | rk[2] = |

196 | _ad0[_ae4[(rk[2] >> 24) ] & 0xff] ^ |

197 | _ad1[_ae4[(rk[2] >> 16) & 0xff] & 0xff] ^ |

198 | _ad2[_ae4[(rk[2] >> 8) & 0xff] & 0xff] ^ |

199 | _ad3[_ae4[(rk[2] ) & 0xff] & 0xff]; |

200 | rk[3] = |

201 | _ad0[_ae4[(rk[3] >> 24) ] & 0xff] ^ |

202 | _ad1[_ae4[(rk[3] >> 16) & 0xff] & 0xff] ^ |

203 | _ad2[_ae4[(rk[3] >> 8) & 0xff] & 0xff] ^ |

204 | _ad3[_ae4[(rk[3] ) & 0xff] & 0xff]; |

205 | #else |

206 | rk[0] = |

207 | _ad0[_ae4[(rk[0] ) & 0xff] & 0xff] ^ |

208 | _ad1[_ae4[(rk[0] >> 8) & 0xff] & 0xff] ^ |

209 | _ad2[_ae4[(rk[0] >> 16) & 0xff] & 0xff] ^ |

210 | _ad3[_ae4[(rk[0] >> 24) ] & 0xff]; |

211 | rk[1] = |

212 | _ad0[_ae4[(rk[1] ) & 0xff] & 0xff] ^ |

213 | _ad1[_ae4[(rk[1] >> 8) & 0xff] & 0xff] ^ |

214 | _ad2[_ae4[(rk[1] >> 16) & 0xff] & 0xff] ^ |

215 | _ad3[_ae4[(rk[1] >> 24) ] & 0xff]; |

216 | rk[2] = |

217 | _ad0[_ae4[(rk[2] ) & 0xff] & 0xff] ^ |

218 | _ad1[_ae4[(rk[2] >> 8) & 0xff] & 0xff] ^ |

219 | _ad2[_ae4[(rk[2] >> 16) & 0xff] & 0xff] ^ |

220 | _ad3[_ae4[(rk[2] >> 24) ] & 0xff]; |

221 | rk[3] = |

222 | _ad0[_ae4[(rk[3] ) & 0xff] & 0xff] ^ |

223 | _ad1[_ae4[(rk[3] >> 8) & 0xff] & 0xff] ^ |

224 | _ad2[_ae4[(rk[3] >> 16) & 0xff] & 0xff] ^ |

225 | _ad3[_ae4[(rk[3] >> 24) ] & 0xff]; |

226 | #endif |

227 | } |

228 | } |

229 | return 0; |

230 | } |

231 | return -1; |

232 | } |

233 | |

234 | int aesSetIV(aesParam* ap, const byte* iv) |

235 | { |

236 | if (iv) |

237 | memcpy(ap->fdback, iv, 16); |

238 | else |

239 | memset(ap->fdback, 0, 16); |

240 | |

241 | return 0; |

242 | } |

243 | |

244 | int aesEncrypt(aesParam* ap, guint32* dst, const guint32* src) |

245 | { |

246 | register guint32 s0, s1, s2, s3; |

247 | register guint32 t0, t1, t2, t3; |

248 | register guint32* rk = ap->k; |

249 | |

250 | s0 = src[0] ^ rk[0]; |

251 | s1 = src[1] ^ rk[1]; |

252 | s2 = src[2] ^ rk[2]; |

253 | s3 = src[3] ^ rk[3]; |

254 | |

255 | etfs(4); /* round 1 */ |

256 | esft(8); /* round 2 */ |

257 | etfs(12); /* round 3 */ |

258 | esft(16); /* round 4 */ |

259 | etfs(20); /* round 5 */ |

260 | esft(24); /* round 6 */ |

261 | etfs(28); /* round 7 */ |

262 | esft(32); /* round 8 */ |

263 | etfs(36); /* round 9 */ |

264 | |

265 | if (ap->nr > 10) |

266 | { |

267 | esft(40); /* round 10 */ |

268 | etfs(44); /* round 11 */ |

269 | if (ap->nr > 12) |

270 | { |

271 | esft(48); /* round 12 */ |

272 | etfs(52); /* round 13 */ |

273 | } |

274 | } |

275 | |

276 | rk += (ap->nr << 2); |

277 | |

278 | elr(); /* last round */ |

279 | |

280 | dst[0] = s0; |

281 | dst[1] = s1; |

282 | dst[2] = s2; |

283 | dst[3] = s3; |

284 | |

285 | return 0; |

286 | } |

287 | |

288 | int aesDecrypt(aesParam* ap, guint32* dst, const guint32* src) |

289 | { |

290 | register guint32 s0, s1, s2, s3; |

291 | register guint32 t0, t1, t2, t3; |

292 | register guint32* rk = ap->k; |

293 | |

294 | s0 = src[0] ^ rk[0]; |

295 | s1 = src[1] ^ rk[1]; |

296 | s2 = src[2] ^ rk[2]; |

297 | s3 = src[3] ^ rk[3]; |

298 | |

299 | dtfs(4); /* round 1 */ |

300 | dsft(8); /* round 2 */ |

301 | dtfs(12); /* round 3 */ |

302 | dsft(16); /* round 4 */ |

303 | dtfs(20); /* round 5 */ |

304 | dsft(24); /* round 6 */ |

305 | dtfs(28); /* round 7 */ |

306 | dsft(32); /* round 8 */ |

307 | dtfs(36); /* round 9 */ |

308 | |

309 | if (ap->nr > 10) |

310 | { |

311 | dsft(40); /* round 10 */ |

312 | dtfs(44); /* round 11 */ |

313 | if (ap->nr > 12) |

314 | { |

315 | dsft(48); /* round 12 */ |

316 | dtfs(52); /* round 13 */ |

317 | } |

318 | } |

319 | |

320 | rk += (ap->nr << 2); |

321 | |

322 | dlr(); /* last round */ |

323 | |

324 | dst[0] = s0; |

325 | dst[1] = s1; |

326 | dst[2] = s2; |

327 | dst[3] = s3; |

328 | |

329 | return 0; |

330 | } |

331 | |

332 | guint32* aesFeedback(aesParam* ap) |

333 | { |

334 | return ap->fdback; |

335 | } |

**Note:**See TracBrowser for help on using the repository browser.