aes_test.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. // aes_test.go - AES tests.
  2. //
  3. // To the extent possible under law, Yawning Angel has waived all copyright
  4. // and related or neighboring rights to aes_test.go, using the Creative
  5. // Commons "CC0" public domain dedication. See LICENSE or
  6. // <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
  7. package bsaes
  8. import (
  9. "bytes"
  10. "crypto/aes"
  11. "crypto/cipher"
  12. "crypto/rand"
  13. "encoding/hex"
  14. "fmt"
  15. "math"
  16. "testing"
  17. "git.schwanenlied.me/yawning/bsaes.git/ct32"
  18. "git.schwanenlied.me/yawning/bsaes.git/ct64"
  19. )
  20. type Impl struct {
  21. name string
  22. ctor func([]byte) cipher.Block
  23. }
  24. var (
  25. implCt32 = &Impl{"ct32", ct32.NewCipher}
  26. implCt64 = &Impl{"ct64", ct64.NewCipher}
  27. implRuntime = &Impl{"runtime", func(k []byte) cipher.Block {
  28. blk, err := NewCipher(k)
  29. if err != nil {
  30. panic("implRuntime: NewCipher failed: " + err.Error())
  31. }
  32. return blk
  33. }}
  34. impls = []*Impl{implCt32, implCt64}
  35. nativeImpl = implCt64
  36. )
  37. // The test vectors are shamelessly stolen from NIST Special Pub. 800-38A,
  38. // my tax dollars at work.
  39. //
  40. // http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
  41. var ecbVectors = []struct {
  42. key string
  43. plaintext string
  44. ciphertext string
  45. }{
  46. // ECB-AES128
  47. {
  48. "2b7e151628aed2a6abf7158809cf4f3c",
  49. "6bc1bee22e409f96e93d7e117393172a",
  50. "3ad77bb40d7a3660a89ecaf32466ef97",
  51. },
  52. {
  53. "2b7e151628aed2a6abf7158809cf4f3c",
  54. "ae2d8a571e03ac9c9eb76fac45af8e51",
  55. "f5d3d58503b9699de785895a96fdbaaf",
  56. },
  57. {
  58. "2b7e151628aed2a6abf7158809cf4f3c",
  59. "30c81c46a35ce411e5fbc1191a0a52ef",
  60. "43b1cd7f598ece23881b00e3ed030688",
  61. },
  62. {
  63. "2b7e151628aed2a6abf7158809cf4f3c",
  64. "f69f2445df4f9b17ad2b417be66c3710",
  65. "7b0c785e27e8ad3f8223207104725dd4",
  66. },
  67. // ECB-AES192
  68. {
  69. "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
  70. "6bc1bee22e409f96e93d7e117393172a",
  71. "bd334f1d6e45f25ff712a214571fa5cc",
  72. },
  73. {
  74. "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
  75. "ae2d8a571e03ac9c9eb76fac45af8e51",
  76. "974104846d0ad3ad7734ecb3ecee4eef",
  77. },
  78. {
  79. "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
  80. "30c81c46a35ce411e5fbc1191a0a52ef",
  81. "ef7afd2270e2e60adce0ba2face6444e",
  82. },
  83. {
  84. "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
  85. "f69f2445df4f9b17ad2b417be66c3710",
  86. "9a4b41ba738d6c72fb16691603c18e0e",
  87. },
  88. // ECB-AES256
  89. {
  90. "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
  91. "6bc1bee22e409f96e93d7e117393172a",
  92. "f3eed1bdb5d2a03c064b5a7e3db181f8",
  93. },
  94. {
  95. "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
  96. "ae2d8a571e03ac9c9eb76fac45af8e51",
  97. "591ccb10d410ed26dc5ba74a31362870",
  98. },
  99. {
  100. "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
  101. "30c81c46a35ce411e5fbc1191a0a52ef",
  102. "b6ed21b99ca6f4f9f153e7b1beafed1d",
  103. },
  104. {
  105. "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
  106. "f69f2445df4f9b17ad2b417be66c3710",
  107. "23304b7a39f9f3ff067d8d8f9e24ecc7",
  108. },
  109. }
  110. func TestECB_SP800_38A(t *testing.T) {
  111. for _, impl := range impls {
  112. t.Logf("Testing implementation: %v\n", impl.name)
  113. for i, vec := range ecbVectors {
  114. key, err := hex.DecodeString(vec.key[:])
  115. if err != nil {
  116. t.Fatal(err)
  117. }
  118. pt, err := hex.DecodeString(vec.plaintext[:])
  119. if err != nil {
  120. t.Fatal(err)
  121. }
  122. ct, err := hex.DecodeString(vec.ciphertext[:])
  123. if err != nil {
  124. t.Fatal(err)
  125. }
  126. b := impl.ctor(key)
  127. var dst [16]byte
  128. b.Encrypt(dst[:], pt)
  129. assertEqual(t, i, ct, dst[:])
  130. b.Decrypt(dst[:], ct)
  131. assertEqual(t, i, pt, dst[:])
  132. }
  133. }
  134. }
  135. var ctrVectors = []struct {
  136. key string
  137. iv string
  138. plaintext string
  139. ciphertext string
  140. }{
  141. // CTR-AES128
  142. {
  143. "2b7e151628aed2a6abf7158809cf4f3c",
  144. "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
  145. "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
  146. "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee",
  147. },
  148. // CTR-AES192
  149. {
  150. "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
  151. "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
  152. "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
  153. "1abc932417521ca24f2b0459fe7e6e0b090339ec0aa6faefd5ccc2c6f4ce8e941e36b26bd1ebc670d1bd1d665620abf74f78a7f6d29809585a97daec58c6b050",
  154. },
  155. // CTR-AES256
  156. {
  157. "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
  158. "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
  159. "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
  160. "601ec313775789a5b7a7f504bbf3d228f443e3ca4d62b59aca84e990cacaf5c52b0930daa23de94ce87017ba2d84988ddfc9c58db67aada613c2dd08457941a6",
  161. },
  162. }
  163. func TestCTR_SP800_38A(t *testing.T) {
  164. for _, impl := range impls {
  165. t.Logf("Testing implementation: %v\n", impl.name)
  166. for i, vec := range ctrVectors {
  167. key, err := hex.DecodeString(vec.key[:])
  168. if err != nil {
  169. t.Fatal(err)
  170. }
  171. iv, err := hex.DecodeString(vec.iv[:])
  172. if err != nil {
  173. t.Fatal(err)
  174. }
  175. ct, err := hex.DecodeString(vec.ciphertext[:])
  176. if err != nil {
  177. t.Fatal(err)
  178. }
  179. pt, err := hex.DecodeString(vec.plaintext[:])
  180. if err != nil {
  181. t.Fatal(err)
  182. }
  183. b := impl.ctor(key)
  184. dst := make([]byte, len(ct))
  185. ctr := cipher.NewCTR(b, iv)
  186. ctr.XORKeyStream(dst, pt)
  187. assertEqual(t, i, ct, dst)
  188. }
  189. }
  190. }
  191. func TestCTR_keystream(t *testing.T) {
  192. var iv [16]byte
  193. for _, impl := range impls {
  194. strideSz := 0
  195. switch impl.name {
  196. case "ct32":
  197. strideSz = 2 * 16
  198. case "ct64":
  199. strideSz = 4 * 16
  200. case "runtime":
  201. // The CTR tests are tailored towards the bsaes CTR
  202. // so there is not much sense in testing `crypto/aes`'s,
  203. // when it's using AES-NI and assembly.
  204. t.Logf("Skipping CTR tests: %v\n", impl.name)
  205. continue
  206. default:
  207. panic("unable to determine stride")
  208. }
  209. t.Logf("Testing implementation: %v\n", impl.name)
  210. key := make([]byte, 16)
  211. if _, err := rand.Read(key[:]); err != nil {
  212. t.Error(err)
  213. t.Fail()
  214. }
  215. for sz := 0; sz <= strideSz; sz++ {
  216. blk := impl.ctor(key[:])
  217. ctr := cipher.NewCTR(blk, iv[:])
  218. refBlk, _ := aes.NewCipher(key[:])
  219. refCtr := cipher.NewCTR(refBlk, iv[:])
  220. n := sz + strideSz + sz
  221. src := make([]byte, n)
  222. dst := make([]byte, n)
  223. check := make([]byte, n)
  224. if _, err := rand.Read(src[:]); err != nil {
  225. t.Error(err)
  226. t.Fail()
  227. }
  228. ctr.XORKeyStream(dst, src[:sz])
  229. ctr.XORKeyStream(dst[sz:], src[sz:sz+strideSz])
  230. ctr.XORKeyStream(dst[sz+strideSz:], src[sz+strideSz:])
  231. refCtr.XORKeyStream(check, src)
  232. assertEqual(t, sz, check, dst)
  233. }
  234. }
  235. }
  236. var cbcDecVectors = []struct {
  237. key string
  238. iv string
  239. ciphertext string
  240. plaintext string
  241. }{
  242. // CBC-AES128
  243. {
  244. "2b7e151628aed2a6abf7158809cf4f3c",
  245. "000102030405060708090a0b0c0d0e0f",
  246. "7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a7",
  247. "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
  248. },
  249. // CBC-AES192
  250. {
  251. "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b",
  252. "000102030405060708090a0b0c0d0e0f",
  253. "4f021db243bc633d7178183a9fa071e8b4d9ada9ad7dedf4e5e738763f69145a571b242012fb7ae07fa9baac3df102e008b0e27988598881d920a9e64f5615cd",
  254. "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
  255. },
  256. // CBC-AES256
  257. {
  258. "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4",
  259. "000102030405060708090a0b0c0d0e0f",
  260. "f58c4c04d6e5f1ba779eabfb5f7bfbd69cfc4e967edb808d679f777bc6702c7d39f23369a9d9bacfa530e26304231461b2eb05e2c39be9fcda6c19078c6a9d1b",
  261. "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710",
  262. },
  263. }
  264. func TestCBCDecrypt_SP800_38A(t *testing.T) {
  265. for _, impl := range impls {
  266. t.Logf("Testing implementation: %v\n", impl.name)
  267. for i, vec := range cbcDecVectors {
  268. key, err := hex.DecodeString(vec.key[:])
  269. if err != nil {
  270. t.Fatal(err)
  271. }
  272. iv, err := hex.DecodeString(vec.iv[:])
  273. if err != nil {
  274. t.Fatal(err)
  275. }
  276. ct, err := hex.DecodeString(vec.ciphertext[:])
  277. if err != nil {
  278. t.Fatal(err)
  279. }
  280. pt, err := hex.DecodeString(vec.plaintext[:])
  281. if err != nil {
  282. t.Fatal(err)
  283. }
  284. b := impl.ctor(key)
  285. dst := make([]byte, len(ct))
  286. cbc := cipher.NewCBCDecrypter(b, iv)
  287. cbc.CryptBlocks(dst, ct)
  288. assertEqual(t, i, pt, dst)
  289. }
  290. }
  291. }
  292. var gcmVectors = []struct {
  293. k string
  294. iv string
  295. a string
  296. p string
  297. c string
  298. t string
  299. }{
  300. // GCM-AES128
  301. {
  302. "00000000000000000000000000000000",
  303. "000000000000000000000000",
  304. "",
  305. "",
  306. "",
  307. "58e2fccefa7e3061367f1d57a4e7455a",
  308. },
  309. {
  310. "00000000000000000000000000000000",
  311. "000000000000000000000000",
  312. "",
  313. "00000000000000000000000000000000",
  314. "0388dace60b6a392f328c2b971b2fe78",
  315. "ab6e47d42cec13bdf53a67b21257bddf",
  316. },
  317. {
  318. "feffe9928665731c6d6a8f9467308308",
  319. "cafebabefacedbaddecaf888",
  320. "",
  321. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
  322. "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985",
  323. "4d5c2af327cd64a62cf35abd2ba6fab4",
  324. },
  325. {
  326. "feffe9928665731c6d6a8f9467308308",
  327. "cafebabefacedbaddecaf888",
  328. "feedfacedeadbeeffeedfacedeadbeefabaddad2",
  329. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
  330. "42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091",
  331. "5bc94fbc3221a5db94fae95ae7121a47",
  332. },
  333. {
  334. "feffe9928665731c6d6a8f9467308308",
  335. "cafebabefacedbad",
  336. "feedfacedeadbeeffeedfacedeadbeefabaddad2",
  337. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
  338. "61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598",
  339. "3612d2e79e3b0785561be14aaca2fccb",
  340. },
  341. {
  342. "feffe9928665731c6d6a8f9467308308",
  343. "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
  344. "feedfacedeadbeeffeedfacedeadbeefabaddad2",
  345. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
  346. "8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5",
  347. "619cc5aefffe0bfa462af43c1699d050",
  348. },
  349. // GCM-AES192
  350. {
  351. "000000000000000000000000000000000000000000000000",
  352. "000000000000000000000000",
  353. "",
  354. "",
  355. "",
  356. "cd33b28ac773f74ba00ed1f312572435",
  357. },
  358. {
  359. "000000000000000000000000000000000000000000000000",
  360. "000000000000000000000000",
  361. "",
  362. "00000000000000000000000000000000",
  363. "98e7247c07f0fe411c267e4384b0f600",
  364. "2ff58d80033927ab8ef4d4587514f0fb",
  365. },
  366. {
  367. "feffe9928665731c6d6a8f9467308308feffe9928665731c",
  368. "cafebabefacedbaddecaf888",
  369. "",
  370. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
  371. "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256",
  372. "9924a7c8587336bfb118024db8674a14",
  373. },
  374. {
  375. "feffe9928665731c6d6a8f9467308308feffe9928665731c",
  376. "cafebabefacedbaddecaf888",
  377. "feedfacedeadbeeffeedfacedeadbeefabaddad2",
  378. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
  379. "3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710",
  380. "2519498e80f1478f37ba55bd6d27618c",
  381. },
  382. {
  383. "feffe9928665731c6d6a8f9467308308feffe9928665731c",
  384. "cafebabefacedbad",
  385. "feedfacedeadbeeffeedfacedeadbeefabaddad2",
  386. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
  387. "0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7",
  388. "65dcc57fcf623a24094fcca40d3533f8",
  389. },
  390. {
  391. "feffe9928665731c6d6a8f9467308308feffe9928665731c",
  392. "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
  393. "feedfacedeadbeeffeedfacedeadbeefabaddad2",
  394. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
  395. "d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b",
  396. "dcf566ff291c25bbb8568fc3d376a6d9",
  397. },
  398. // GCM-AES256
  399. {
  400. "0000000000000000000000000000000000000000000000000000000000000000",
  401. "000000000000000000000000",
  402. "",
  403. "",
  404. "",
  405. "530f8afbc74536b9a963b4f1c4cb738b",
  406. },
  407. {
  408. "0000000000000000000000000000000000000000000000000000000000000000",
  409. "000000000000000000000000",
  410. "",
  411. "00000000000000000000000000000000",
  412. "cea7403d4d606b6e074ec5d3baf39d18",
  413. "d0d1c8a799996bf0265b98b5d48ab919",
  414. },
  415. {
  416. "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
  417. "cafebabefacedbaddecaf888",
  418. "",
  419. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255",
  420. "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad",
  421. "b094dac5d93471bdec1a502270e3cc6c",
  422. },
  423. {
  424. "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
  425. "cafebabefacedbaddecaf888",
  426. "feedfacedeadbeeffeedfacedeadbeefabaddad2",
  427. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
  428. "522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662",
  429. "76fc6ece0f4e1768cddf8853bb2d551b",
  430. },
  431. {
  432. "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
  433. "cafebabefacedbad",
  434. "feedfacedeadbeeffeedfacedeadbeefabaddad2",
  435. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
  436. "c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f",
  437. "3a337dbf46a792c45e454913fe2ea8f2",
  438. },
  439. {
  440. "feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308",
  441. "9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b",
  442. "feedfacedeadbeeffeedfacedeadbeefabaddad2",
  443. "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39",
  444. "5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f",
  445. "a44a8266ee1c8eb0c8b5d4cf5ae9f19a",
  446. },
  447. }
  448. func TestGCM(t *testing.T) {
  449. for _, impl := range impls {
  450. t.Logf("Testing implementation: %v\n", impl.name)
  451. for i, vec := range gcmVectors {
  452. key, err := hex.DecodeString(vec.k[:])
  453. if err != nil {
  454. t.Fatal(err)
  455. }
  456. iv, err := hex.DecodeString(vec.iv[:])
  457. if err != nil {
  458. t.Fatal(err)
  459. }
  460. a, err := hex.DecodeString(vec.a[:])
  461. if err != nil {
  462. t.Fatal(err)
  463. }
  464. p, err := hex.DecodeString(vec.p[:])
  465. if err != nil {
  466. t.Fatal(err)
  467. }
  468. c, err := hex.DecodeString(vec.c[:])
  469. if err != nil {
  470. t.Fatal(err)
  471. }
  472. tag, err := hex.DecodeString(vec.t[:])
  473. if err != nil {
  474. t.Fatal(err)
  475. }
  476. sealOut := make([]byte, 0, len(c)+len(tag))
  477. sealOut = append(sealOut, c...)
  478. sealOut = append(sealOut, tag...)
  479. b := impl.ctor(key[:])
  480. g, err := cipher.NewGCMWithNonceSize(b, len(iv))
  481. if err != nil {
  482. t.Fatal(err)
  483. }
  484. ct := g.Seal(nil, iv, p, a)
  485. assertEqual(t, i, sealOut, ct)
  486. pt, err := g.Open(nil, iv, ct, a)
  487. if err != nil {
  488. t.Fatal(err)
  489. }
  490. assertEqual(t, i, p, pt)
  491. }
  492. }
  493. }
  494. func assertEqual(t *testing.T, idx int, expected, actual []byte) {
  495. if !bytes.Equal(expected, actual) {
  496. for i, v := range actual {
  497. if expected[i] != v {
  498. t.Errorf("[%d] first mismatch at offset: %d (%02x != %02x)", idx, i, expected[i], v)
  499. break
  500. }
  501. }
  502. t.Errorf("expected: %s", hex.Dump(expected))
  503. t.Errorf("actual: %s", hex.Dump(actual))
  504. t.FailNow()
  505. }
  506. }
  507. var ecbBenchOutput [16]byte
  508. func doBenchECB(b *testing.B, impl *Impl, ksz int) {
  509. var src, dst, check [16]byte
  510. key := make([]byte, ksz)
  511. if _, err := rand.Read(key[:]); err != nil {
  512. b.Error(err)
  513. b.Fail()
  514. }
  515. blk := impl.ctor(key[:])
  516. b.SetBytes(16)
  517. b.ResetTimer()
  518. for i := 0; i < b.N; i++ {
  519. b.StartTimer()
  520. blk.Encrypt(dst[:], src[:])
  521. b.StopTimer()
  522. // Check forward/back because, why not.
  523. blk.Decrypt(check[:], dst[:])
  524. if !bytes.Equal(check[:], src[:]) {
  525. b.Fatalf("decrypt produced invalid output")
  526. }
  527. copy(src[:], dst[:])
  528. }
  529. copy(ecbBenchOutput[:], dst[:])
  530. }
  531. var benchOutput []byte
  532. func doBenchCTR(b *testing.B, impl *Impl, ksz, n int) {
  533. var iv [16]byte
  534. key := make([]byte, ksz)
  535. if _, err := rand.Read(key[:]); err != nil {
  536. b.Error(err)
  537. b.Fail()
  538. }
  539. blk := impl.ctor(key[:])
  540. ctr := cipher.NewCTR(blk, iv[:])
  541. src := make([]byte, n)
  542. dst := make([]byte, n)
  543. b.SetBytes(int64(n))
  544. b.ResetTimer()
  545. for i := 0; i < b.N; i++ {
  546. ctr.XORKeyStream(dst, src)
  547. }
  548. benchOutput = dst
  549. }
  550. func doBenchCBC(b *testing.B, impl *Impl, ksz, n int) {
  551. var iv [16]byte
  552. key := make([]byte, ksz)
  553. if _, err := rand.Read(key[:]); err != nil {
  554. b.Error(err)
  555. b.Fail()
  556. }
  557. blk := impl.ctor(key[:])
  558. cbc := cipher.NewCBCDecrypter(blk, iv[:])
  559. src := make([]byte, n)
  560. dst := make([]byte, n)
  561. b.SetBytes(int64(n))
  562. b.ResetTimer()
  563. for i := 0; i < b.N; i++ {
  564. cbc.CryptBlocks(dst, src)
  565. }
  566. benchOutput = dst
  567. }
  568. func doBenchGCM(b *testing.B, impl *Impl, ksz, n int) {
  569. var iv [96 / 8]byte
  570. key := make([]byte, ksz)
  571. if _, err := rand.Read(key[:]); err != nil {
  572. b.Error(err)
  573. b.Fail()
  574. }
  575. blk := impl.ctor(key[:])
  576. gcm, err := cipher.NewGCM(blk)
  577. if err != nil {
  578. b.Error(err)
  579. b.Fail()
  580. }
  581. src := make([]byte, n)
  582. var dst []byte
  583. b.SetBytes(int64(n))
  584. b.ResetTimer()
  585. for i := 0; i < b.N; i++ {
  586. dst = gcm.Seal(nil, iv[:], src, nil)
  587. }
  588. benchOutput = dst
  589. }
  590. func implIsNative(impl *Impl) bool {
  591. return impl == nativeImpl || impl == implRuntime
  592. }
  593. func doBench(b *testing.B, impl *Impl) {
  594. if testing.Short() && !implIsNative(impl) {
  595. b.SkipNow()
  596. }
  597. b.SetParallelism(1) // We want per-core figures.
  598. b.Run("ECB-AES128", func(b *testing.B) { doBenchECB(b, implCt32, 16) })
  599. if !testing.Short() { // No one cares about this mode.
  600. b.Run("ECB-AES192", func(b *testing.B) { doBenchECB(b, implCt32, 24) })
  601. }
  602. b.Run("ECB-AES256", func(b *testing.B) { doBenchECB(b, implCt32, 32) })
  603. for _, sz := range []int{16, 64, 256, 1024, 8192, 16384} {
  604. n := fmt.Sprintf("CTR-AES128_%d", sz)
  605. b.Run(n, func(b *testing.B) { doBenchCTR(b, impl, 16, sz) })
  606. }
  607. for _, sz := range []int{16, 64, 256, 1024, 8192, 16384} {
  608. n := fmt.Sprintf("DecryptCBC-AES128_%d", sz)
  609. b.Run(n, func(b *testing.B) { doBenchCBC(b, impl, 16, sz) })
  610. }
  611. for _, sz := range []int{16, 64, 256, 1024, 8192, 16384} {
  612. n := fmt.Sprintf("GCM-AES128_%d", sz)
  613. b.Run(n, func(b *testing.B) { doBenchGCM(b, impl, 16, sz) })
  614. }
  615. }
  616. func Benchmark_ct32(b *testing.B) {
  617. doBench(b, implCt32)
  618. }
  619. func Benchmark_ct64(b *testing.B) {
  620. doBench(b, implCt64)
  621. }
  622. func Benchmark_runtime(b *testing.B) {
  623. if !useCryptoAES {
  624. b.SkipNow()
  625. }
  626. doBench(b, implRuntime)
  627. }
  628. func init() {
  629. maxUintptr := uint64(^uintptr(0))
  630. switch maxUintptr {
  631. case math.MaxUint32:
  632. nativeImpl = implCt32
  633. case math.MaxUint64:
  634. nativeImpl = implCt64
  635. default:
  636. panic("bsaes: unsupported architecture")
  637. }
  638. if useCryptoAES {
  639. impls = append(impls, implRuntime)
  640. }
  641. }