You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

139 line
4.4 KiB

  1. // Copyright 2012 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 xts implements the XTS cipher mode as specified in IEEE P1619/D16.
  5. //
  6. // XTS mode is typically used for disk encryption, which presents a number of
  7. // novel problems that make more common modes inapplicable. The disk is
  8. // conceptually an array of sectors and we must be able to encrypt and decrypt
  9. // a sector in isolation. However, an attacker must not be able to transpose
  10. // two sectors of plaintext by transposing their ciphertext.
  11. //
  12. // XTS wraps a block cipher with Rogaway's XEX mode in order to build a
  13. // tweakable block cipher. This allows each sector to have a unique tweak and
  14. // effectively create a unique key for each sector.
  15. //
  16. // XTS does not provide any authentication. An attacker can manipulate the
  17. // ciphertext and randomise a block (16 bytes) of the plaintext.
  18. //
  19. // (Note: this package does not implement ciphertext-stealing so sectors must
  20. // be a multiple of 16 bytes.)
  21. package xts // import "golang.org/x/crypto/xts"
  22. import (
  23. "crypto/cipher"
  24. "errors"
  25. )
  26. // Cipher contains an expanded key structure. It doesn't contain mutable state
  27. // and therefore can be used concurrently.
  28. type Cipher struct {
  29. k1, k2 cipher.Block
  30. }
  31. // blockSize is the block size that the underlying cipher must have. XTS is
  32. // only defined for 16-byte ciphers.
  33. const blockSize = 16
  34. // NewCipher creates a Cipher given a function for creating the underlying
  35. // block cipher (which must have a block size of 16 bytes). The key must be
  36. // twice the length of the underlying cipher's key.
  37. func NewCipher(cipherFunc func([]byte) (cipher.Block, error), key []byte) (c *Cipher, err error) {
  38. c = new(Cipher)
  39. if c.k1, err = cipherFunc(key[:len(key)/2]); err != nil {
  40. return
  41. }
  42. c.k2, err = cipherFunc(key[len(key)/2:])
  43. if c.k1.BlockSize() != blockSize {
  44. err = errors.New("xts: cipher does not have a block size of 16")
  45. }
  46. return
  47. }
  48. // Encrypt encrypts a sector of plaintext and puts the result into ciphertext.
  49. // Plaintext and ciphertext may be the same slice but should not overlap.
  50. // Sectors must be a multiple of 16 bytes and less than 2²⁴ bytes.
  51. func (c *Cipher) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
  52. if len(ciphertext) < len(plaintext) {
  53. panic("xts: ciphertext is smaller than plaintext")
  54. }
  55. if len(plaintext)%blockSize != 0 {
  56. panic("xts: plaintext is not a multiple of the block size")
  57. }
  58. var tweak [blockSize]byte
  59. for i := 0; i < 8; i++ {
  60. tweak[i] = byte(sectorNum)
  61. sectorNum >>= 8
  62. }
  63. c.k2.Encrypt(tweak[:], tweak[:])
  64. for i := 0; i < len(plaintext); i += blockSize {
  65. for j := 0; j < blockSize; j++ {
  66. ciphertext[i+j] = plaintext[i+j] ^ tweak[j]
  67. }
  68. c.k1.Encrypt(ciphertext[i:], ciphertext[i:])
  69. for j := 0; j < blockSize; j++ {
  70. ciphertext[i+j] ^= tweak[j]
  71. }
  72. mul2(&tweak)
  73. }
  74. }
  75. // Decrypt decrypts a sector of ciphertext and puts the result into plaintext.
  76. // Plaintext and ciphertext may be the same slice but should not overlap.
  77. // Sectors must be a multiple of 16 bytes and less than 2²⁴ bytes.
  78. func (c *Cipher) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
  79. if len(plaintext) < len(ciphertext) {
  80. panic("xts: plaintext is smaller than ciphertext")
  81. }
  82. if len(ciphertext)%blockSize != 0 {
  83. panic("xts: ciphertext is not a multiple of the block size")
  84. }
  85. var tweak [blockSize]byte
  86. for i := 0; i < 8; i++ {
  87. tweak[i] = byte(sectorNum)
  88. sectorNum >>= 8
  89. }
  90. c.k2.Encrypt(tweak[:], tweak[:])
  91. for i := 0; i < len(plaintext); i += blockSize {
  92. for j := 0; j < blockSize; j++ {
  93. plaintext[i+j] = ciphertext[i+j] ^ tweak[j]
  94. }
  95. c.k1.Decrypt(plaintext[i:], plaintext[i:])
  96. for j := 0; j < blockSize; j++ {
  97. plaintext[i+j] ^= tweak[j]
  98. }
  99. mul2(&tweak)
  100. }
  101. }
  102. // mul2 multiplies tweak by 2 in GF(2¹²⁸) with an irreducible polynomial of
  103. // x¹²⁸ + x⁷ + x² + x + 1.
  104. func mul2(tweak *[blockSize]byte) {
  105. var carryIn byte
  106. for j := range tweak {
  107. carryOut := tweak[j] >> 7
  108. tweak[j] = (tweak[j] << 1) + carryIn
  109. carryIn = carryOut
  110. }
  111. if carryIn != 0 {
  112. // If we have a carry bit then we need to subtract a multiple
  113. // of the irreducible polynomial (x¹²⁸ + x⁷ + x² + x + 1).
  114. // By dropping the carry bit, we're subtracting the x^128 term
  115. // so all that remains is to subtract x⁷ + x² + x + 1.
  116. // Subtraction (and addition) in this representation is just
  117. // XOR.
  118. tweak[0] ^= 1<<7 | 1<<2 | 1<<1 | 1
  119. }
  120. }