cipher.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package xtea implements XTEA encryption, as defined in Needham and Wheeler's
  5. // 1997 technical report, "Tea extensions."
  6. //
  7. // XTEA is a legacy cipher and its short block size makes it vulnerable to
  8. // birthday bound attacks (see https://sweet32.info). It should only be used
  9. // where compatibility with legacy systems, not security, is the goal.
  10. //
  11. // Deprecated: any new system should use AES (from crypto/aes, if necessary in
  12. // an AEAD mode like crypto/cipher.NewGCM) or XChaCha20-Poly1305 (from
  13. // golang.org/x/crypto/chacha20poly1305).
  14. package xtea // import "golang.org/x/crypto/xtea"
  15. // For details, see http://www.cix.co.uk/~klockstone/xtea.pdf
  16. import "strconv"
  17. // The XTEA block size in bytes.
  18. const BlockSize = 8
  19. // A Cipher is an instance of an XTEA cipher using a particular key.
  20. type Cipher struct {
  21. // table contains a series of precalculated values that are used each round.
  22. table [64]uint32
  23. }
  24. type KeySizeError int
  25. func (k KeySizeError) Error() string {
  26. return "crypto/xtea: invalid key size " + strconv.Itoa(int(k))
  27. }
  28. // NewCipher creates and returns a new Cipher.
  29. // The key argument should be the XTEA key.
  30. // XTEA only supports 128 bit (16 byte) keys.
  31. func NewCipher(key []byte) (*Cipher, error) {
  32. k := len(key)
  33. switch k {
  34. default:
  35. return nil, KeySizeError(k)
  36. case 16:
  37. break
  38. }
  39. c := new(Cipher)
  40. initCipher(c, key)
  41. return c, nil
  42. }
  43. // BlockSize returns the XTEA block size, 8 bytes.
  44. // It is necessary to satisfy the Block interface in the
  45. // package "crypto/cipher".
  46. func (c *Cipher) BlockSize() int { return BlockSize }
  47. // Encrypt encrypts the 8 byte buffer src using the key and stores the result in dst.
  48. // Note that for amounts of data larger than a block,
  49. // it is not safe to just call Encrypt on successive blocks;
  50. // instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
  51. func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c, dst, src) }
  52. // Decrypt decrypts the 8 byte buffer src using the key and stores the result in dst.
  53. func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c, dst, src) }
  54. // initCipher initializes the cipher context by creating a look up table
  55. // of precalculated values that are based on the key.
  56. func initCipher(c *Cipher, key []byte) {
  57. // Load the key into four uint32s
  58. var k [4]uint32
  59. for i := 0; i < len(k); i++ {
  60. j := i << 2 // Multiply by 4
  61. k[i] = uint32(key[j+0])<<24 | uint32(key[j+1])<<16 | uint32(key[j+2])<<8 | uint32(key[j+3])
  62. }
  63. // Precalculate the table
  64. const delta = 0x9E3779B9
  65. var sum uint32
  66. // Two rounds of XTEA applied per loop
  67. for i := 0; i < numRounds; {
  68. c.table[i] = sum + k[sum&3]
  69. i++
  70. sum += delta
  71. c.table[i] = sum + k[(sum>>11)&3]
  72. i++
  73. }
  74. }