Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

366 wiersze
9.2 KiB

  1. package main
  2. import (
  3. "crypto"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/des"
  7. "crypto/hmac"
  8. _ "crypto/md5"
  9. "crypto/rc4"
  10. _ "crypto/sha1"
  11. _ "crypto/sha256"
  12. _ "crypto/sha512"
  13. "encoding/hex"
  14. "flag"
  15. "fmt"
  16. "os"
  17. )
  18. var bulkCipher *string = flag.String("cipher", "", "The bulk cipher to use")
  19. var mac *string = flag.String("mac", "", "The hash function to use in the MAC")
  20. var implicitIV *bool = flag.Bool("implicit-iv", false, "If true, generate tests for a cipher using a pre-TLS-1.0 implicit IV")
  21. var ssl3 *bool = flag.Bool("ssl3", false, "If true, use the SSLv3 MAC and padding rather than TLS")
  22. // rc4Stream produces a deterministic stream of pseudorandom bytes. This is to
  23. // make this script idempotent.
  24. type rc4Stream struct {
  25. cipher *rc4.Cipher
  26. }
  27. func newRc4Stream(seed string) (*rc4Stream, error) {
  28. cipher, err := rc4.NewCipher([]byte(seed))
  29. if err != nil {
  30. return nil, err
  31. }
  32. return &rc4Stream{cipher}, nil
  33. }
  34. func (rs *rc4Stream) fillBytes(p []byte) {
  35. for i := range p {
  36. p[i] = 0
  37. }
  38. rs.cipher.XORKeyStream(p, p)
  39. }
  40. func getHash(name string) (crypto.Hash, bool) {
  41. switch name {
  42. case "md5":
  43. return crypto.MD5, true
  44. case "sha1":
  45. return crypto.SHA1, true
  46. case "sha256":
  47. return crypto.SHA256, true
  48. case "sha384":
  49. return crypto.SHA384, true
  50. default:
  51. return 0, false
  52. }
  53. }
  54. func getKeySize(name string) int {
  55. switch name {
  56. case "aes128":
  57. return 16
  58. case "aes256":
  59. return 32
  60. case "3des":
  61. return 24
  62. default:
  63. return 0
  64. }
  65. }
  66. func newBlockCipher(name string, key []byte) (cipher.Block, error) {
  67. switch name {
  68. case "aes128":
  69. return aes.NewCipher(key)
  70. case "aes256":
  71. return aes.NewCipher(key)
  72. case "3des":
  73. return des.NewTripleDESCipher(key)
  74. default:
  75. return nil, fmt.Errorf("unknown cipher '%s'", name)
  76. }
  77. }
  78. var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}
  79. var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c}
  80. func ssl30MAC(hash crypto.Hash, key, input, ad []byte) []byte {
  81. padLength := 48
  82. if hash.Size() == 20 {
  83. padLength = 40
  84. }
  85. h := hash.New()
  86. h.Write(key)
  87. h.Write(ssl30Pad1[:padLength])
  88. h.Write(ad)
  89. h.Write(input)
  90. digestBuf := h.Sum(nil)
  91. h.Reset()
  92. h.Write(key)
  93. h.Write(ssl30Pad2[:padLength])
  94. h.Write(digestBuf)
  95. return h.Sum(digestBuf[:0])
  96. }
  97. type testCase struct {
  98. digest []byte
  99. key []byte
  100. nonce []byte
  101. input []byte
  102. ad []byte
  103. ciphertext []byte
  104. tag []byte
  105. tag_len int
  106. noSeal bool
  107. fails bool
  108. }
  109. // options adds additional options for a test.
  110. type options struct {
  111. // extraPadding causes an extra block of padding to be added.
  112. extraPadding bool
  113. // maximalPadding causes 256 bytes of padding to be added.
  114. maximalPadding bool
  115. // wrongPadding causes one of the padding bytes to be wrong.
  116. wrongPadding bool
  117. // wrongPaddingOffset specifies the byte offset of the incorrect padding
  118. // byte.
  119. wrongPaddingOffset int
  120. // noPadding causes padding is to be omitted. The plaintext + MAC must
  121. // be a multiple of the block size.
  122. noPadding bool
  123. // omitMAC causes the MAC to be omitted.
  124. omitMAC bool
  125. }
  126. func makeTestCase(length int, options options) (*testCase, error) {
  127. rand, err := newRc4Stream("input stream")
  128. if err != nil {
  129. return nil, err
  130. }
  131. input := make([]byte, length)
  132. rand.fillBytes(input)
  133. var adFull []byte
  134. if *ssl3 {
  135. adFull = make([]byte, 11)
  136. } else {
  137. adFull = make([]byte, 13)
  138. }
  139. ad := adFull[:len(adFull)-2]
  140. rand.fillBytes(ad)
  141. adFull[len(adFull)-2] = uint8(length >> 8)
  142. adFull[len(adFull)-1] = uint8(length & 0xff)
  143. hash, ok := getHash(*mac)
  144. if !ok {
  145. return nil, fmt.Errorf("unknown hash function '%s'", *mac)
  146. }
  147. macKey := make([]byte, hash.Size())
  148. rand.fillBytes(macKey)
  149. var digest []byte
  150. if *ssl3 {
  151. if hash != crypto.SHA1 && hash != crypto.MD5 {
  152. return nil, fmt.Errorf("invalid hash for SSLv3: '%s'", *mac)
  153. }
  154. digest = ssl30MAC(hash, macKey, input, adFull)
  155. } else {
  156. h := hmac.New(hash.New, macKey)
  157. h.Write(adFull)
  158. h.Write(input)
  159. digest = h.Sum(nil)
  160. }
  161. size := getKeySize(*bulkCipher)
  162. if size == 0 {
  163. return nil, fmt.Errorf("unknown cipher '%s'", *bulkCipher)
  164. }
  165. encKey := make([]byte, size)
  166. rand.fillBytes(encKey)
  167. var fixedIV []byte
  168. var nonce []byte
  169. var sealed []byte
  170. var noSeal, fails bool
  171. block, err := newBlockCipher(*bulkCipher, encKey)
  172. if err != nil {
  173. return nil, err
  174. }
  175. iv := make([]byte, block.BlockSize())
  176. rand.fillBytes(iv)
  177. if *implicitIV || *ssl3 {
  178. fixedIV = iv
  179. } else {
  180. nonce = iv
  181. }
  182. cbc := cipher.NewCBCEncrypter(block, iv)
  183. sealed = make([]byte, 0, len(input)+len(digest)+cbc.BlockSize())
  184. sealed = append(sealed, input...)
  185. if options.omitMAC {
  186. noSeal = true
  187. fails = true
  188. } else {
  189. sealed = append(sealed, digest...)
  190. }
  191. paddingLen := cbc.BlockSize() - (len(sealed) % cbc.BlockSize())
  192. if options.noPadding {
  193. if paddingLen != cbc.BlockSize() {
  194. return nil, fmt.Errorf("invalid length for noPadding")
  195. }
  196. noSeal = true
  197. fails = true
  198. } else {
  199. if options.extraPadding || options.maximalPadding {
  200. if options.extraPadding {
  201. paddingLen += cbc.BlockSize()
  202. } else {
  203. if paddingLen != cbc.BlockSize() {
  204. return nil, fmt.Errorf("invalid length for maximalPadding")
  205. }
  206. paddingLen = 256
  207. }
  208. noSeal = true
  209. if *ssl3 {
  210. // SSLv3 padding must be minimal.
  211. fails = true
  212. }
  213. }
  214. if *ssl3 {
  215. sealed = append(sealed, make([]byte, paddingLen-1)...)
  216. sealed = append(sealed, byte(paddingLen-1))
  217. } else {
  218. pad := make([]byte, paddingLen)
  219. for i := range pad {
  220. pad[i] = byte(paddingLen - 1)
  221. }
  222. sealed = append(sealed, pad...)
  223. }
  224. if options.wrongPadding {
  225. if options.wrongPaddingOffset >= paddingLen {
  226. return nil, fmt.Errorf("invalid wrongPaddingOffset")
  227. }
  228. sealed[len(sealed)-paddingLen+options.wrongPaddingOffset]++
  229. noSeal = true
  230. if !*ssl3 {
  231. // TLS specifies the all the padding bytes.
  232. fails = true
  233. }
  234. }
  235. }
  236. cbc.CryptBlocks(sealed, sealed)
  237. key := make([]byte, 0, len(macKey)+len(encKey)+len(fixedIV))
  238. key = append(key, macKey...)
  239. key = append(key, encKey...)
  240. key = append(key, fixedIV...)
  241. t := &testCase{
  242. digest: digest,
  243. key: key,
  244. nonce: nonce,
  245. input: input,
  246. ad: ad,
  247. ciphertext: sealed[:len(input)],
  248. tag: sealed[len(input):],
  249. tag_len: hash.Size(),
  250. noSeal: noSeal,
  251. fails: fails,
  252. }
  253. return t, nil
  254. }
  255. func printTestCase(t *testCase) {
  256. fmt.Printf("# DIGEST: %s\n", hex.EncodeToString(t.digest))
  257. fmt.Printf("KEY: %s\n", hex.EncodeToString(t.key))
  258. fmt.Printf("NONCE: %s\n", hex.EncodeToString(t.nonce))
  259. fmt.Printf("IN: %s\n", hex.EncodeToString(t.input))
  260. fmt.Printf("AD: %s\n", hex.EncodeToString(t.ad))
  261. fmt.Printf("CT: %s\n", hex.EncodeToString(t.ciphertext))
  262. fmt.Printf("TAG: %s\n", hex.EncodeToString(t.tag))
  263. fmt.Printf("TAG_LEN: %d\n", t.tag_len)
  264. if t.noSeal {
  265. fmt.Printf("NO_SEAL: 01\n")
  266. }
  267. if t.fails {
  268. fmt.Printf("FAILS: 01\n")
  269. }
  270. }
  271. func addTestCase(length int, options options) {
  272. t, err := makeTestCase(length, options)
  273. if err != nil {
  274. fmt.Fprintf(os.Stderr, "%s\n", err)
  275. os.Exit(1)
  276. }
  277. printTestCase(t)
  278. fmt.Printf("\n")
  279. }
  280. func main() {
  281. flag.Parse()
  282. commandLine := fmt.Sprintf("go run make_legacy_aead_tests.go -cipher %s -mac %s", *bulkCipher, *mac)
  283. if *implicitIV {
  284. commandLine += " -implicit-iv"
  285. }
  286. if *ssl3 {
  287. commandLine += " -ssl3"
  288. }
  289. fmt.Printf("# Generated by\n")
  290. fmt.Printf("# %s\n", commandLine)
  291. fmt.Printf("#\n")
  292. fmt.Printf("# Note: aead_test's input format splits the ciphertext and tag positions of the\n")
  293. fmt.Printf("# sealed input. But these legacy AEADs are MAC-then-encrypt and so the 'TAG' may\n")
  294. fmt.Printf("# also include padding. We write the byte length of the MAC to 'TAG_LEN' and\n")
  295. fmt.Printf("# include the unencrypted MAC in the 'DIGEST' tag above # each test case.\n")
  296. fmt.Printf("# each test case.\n")
  297. fmt.Printf("\n")
  298. // For CBC-mode ciphers, emit tests for padding flexibility.
  299. fmt.Printf("# Test with non-minimal padding.\n")
  300. addTestCase(5, options{extraPadding: true})
  301. fmt.Printf("# Test with bad padding values.\n")
  302. addTestCase(5, options{wrongPadding: true})
  303. hash, ok := getHash(*mac)
  304. if !ok {
  305. panic("unknown hash")
  306. }
  307. fmt.Printf("# Test with no padding.\n")
  308. addTestCase(64-hash.Size(), options{noPadding: true})
  309. fmt.Printf("# Test with maximal padding.\n")
  310. addTestCase(64-hash.Size(), options{maximalPadding: true})
  311. fmt.Printf("# Test if the unpadded input is too short for a MAC, but not publicly so.\n")
  312. addTestCase(0, options{omitMAC: true, maximalPadding: true})
  313. fmt.Printf("# Test that each byte of incorrect padding is noticed.\n")
  314. for i := 0; i < 256; i++ {
  315. addTestCase(64-hash.Size(), options{
  316. maximalPadding: true,
  317. wrongPadding: true,
  318. wrongPaddingOffset: i,
  319. })
  320. }
  321. // Generate long enough of input to cover a non-zero num_starting_blocks
  322. // value in the constant-time CBC logic.
  323. for l := 0; l < 500; l += 5 {
  324. addTestCase(l, options{})
  325. }
  326. }