cipher.mx raw

   1  // Copyright 2011 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  
   5  package des
   6  
   7  import (
   8  	"crypto/cipher"
   9  	"crypto/internal/fips140/alias"
  10  	"crypto/internal/fips140only"
  11  	"errors"
  12  	"internal/byteorder"
  13  	"strconv"
  14  )
  15  
  16  // The DES block size in bytes.
  17  const BlockSize = 8
  18  
  19  type KeySizeError int
  20  
  21  func (k KeySizeError) Error() string {
  22  	return "crypto/des: invalid key size " + strconv.Itoa(int(k))
  23  }
  24  
  25  // desCipher is an instance of DES encryption.
  26  type desCipher struct {
  27  	subkeys [16]uint64
  28  }
  29  
  30  // NewCipher creates and returns a new [cipher.Block].
  31  func NewCipher(key []byte) (cipher.Block, error) {
  32  	if fips140only.Enabled {
  33  		return nil, errors.New("crypto/des: use of DES is not allowed in FIPS 140-only mode")
  34  	}
  35  
  36  	if len(key) != 8 {
  37  		return nil, KeySizeError(len(key))
  38  	}
  39  
  40  	c := &desCipher{}
  41  	c.generateSubkeys(key)
  42  	return c, nil
  43  }
  44  
  45  func (c *desCipher) BlockSize() int { return BlockSize }
  46  
  47  func (c *desCipher) Encrypt(dst, src []byte) {
  48  	if len(src) < BlockSize {
  49  		panic("crypto/des: input not full block")
  50  	}
  51  	if len(dst) < BlockSize {
  52  		panic("crypto/des: output not full block")
  53  	}
  54  	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
  55  		panic("crypto/des: invalid buffer overlap")
  56  	}
  57  	cryptBlock(c.subkeys[:], dst, src, false)
  58  }
  59  
  60  func (c *desCipher) Decrypt(dst, src []byte) {
  61  	if len(src) < BlockSize {
  62  		panic("crypto/des: input not full block")
  63  	}
  64  	if len(dst) < BlockSize {
  65  		panic("crypto/des: output not full block")
  66  	}
  67  	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
  68  		panic("crypto/des: invalid buffer overlap")
  69  	}
  70  	cryptBlock(c.subkeys[:], dst, src, true)
  71  }
  72  
  73  // A tripleDESCipher is an instance of TripleDES encryption.
  74  type tripleDESCipher struct {
  75  	cipher1, cipher2, cipher3 desCipher
  76  }
  77  
  78  // NewTripleDESCipher creates and returns a new [cipher.Block].
  79  func NewTripleDESCipher(key []byte) (cipher.Block, error) {
  80  	if fips140only.Enabled {
  81  		return nil, errors.New("crypto/des: use of TripleDES is not allowed in FIPS 140-only mode")
  82  	}
  83  
  84  	if len(key) != 24 {
  85  		return nil, KeySizeError(len(key))
  86  	}
  87  
  88  	c := &tripleDESCipher{}
  89  	c.cipher1.generateSubkeys(key[:8])
  90  	c.cipher2.generateSubkeys(key[8:16])
  91  	c.cipher3.generateSubkeys(key[16:])
  92  	return c, nil
  93  }
  94  
  95  func (c *tripleDESCipher) BlockSize() int { return BlockSize }
  96  
  97  func (c *tripleDESCipher) Encrypt(dst, src []byte) {
  98  	if len(src) < BlockSize {
  99  		panic("crypto/des: input not full block")
 100  	}
 101  	if len(dst) < BlockSize {
 102  		panic("crypto/des: output not full block")
 103  	}
 104  	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 105  		panic("crypto/des: invalid buffer overlap")
 106  	}
 107  
 108  	b := byteorder.BEUint64(src)
 109  	b = permuteInitialBlock(b)
 110  	left, right := uint32(b>>32), uint32(b)
 111  
 112  	left = (left << 1) | (left >> 31)
 113  	right = (right << 1) | (right >> 31)
 114  
 115  	for i := 0; i < 8; i++ {
 116  		left, right = feistel(left, right, c.cipher1.subkeys[2*i], c.cipher1.subkeys[2*i+1])
 117  	}
 118  	for i := 0; i < 8; i++ {
 119  		right, left = feistel(right, left, c.cipher2.subkeys[15-2*i], c.cipher2.subkeys[15-(2*i+1)])
 120  	}
 121  	for i := 0; i < 8; i++ {
 122  		left, right = feistel(left, right, c.cipher3.subkeys[2*i], c.cipher3.subkeys[2*i+1])
 123  	}
 124  
 125  	left = (left << 31) | (left >> 1)
 126  	right = (right << 31) | (right >> 1)
 127  
 128  	preOutput := (uint64(right) << 32) | uint64(left)
 129  	byteorder.BEPutUint64(dst, permuteFinalBlock(preOutput))
 130  }
 131  
 132  func (c *tripleDESCipher) Decrypt(dst, src []byte) {
 133  	if len(src) < BlockSize {
 134  		panic("crypto/des: input not full block")
 135  	}
 136  	if len(dst) < BlockSize {
 137  		panic("crypto/des: output not full block")
 138  	}
 139  	if alias.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
 140  		panic("crypto/des: invalid buffer overlap")
 141  	}
 142  
 143  	b := byteorder.BEUint64(src)
 144  	b = permuteInitialBlock(b)
 145  	left, right := uint32(b>>32), uint32(b)
 146  
 147  	left = (left << 1) | (left >> 31)
 148  	right = (right << 1) | (right >> 31)
 149  
 150  	for i := 0; i < 8; i++ {
 151  		left, right = feistel(left, right, c.cipher3.subkeys[15-2*i], c.cipher3.subkeys[15-(2*i+1)])
 152  	}
 153  	for i := 0; i < 8; i++ {
 154  		right, left = feistel(right, left, c.cipher2.subkeys[2*i], c.cipher2.subkeys[2*i+1])
 155  	}
 156  	for i := 0; i < 8; i++ {
 157  		left, right = feistel(left, right, c.cipher1.subkeys[15-2*i], c.cipher1.subkeys[15-(2*i+1)])
 158  	}
 159  
 160  	left = (left << 31) | (left >> 1)
 161  	right = (right << 31) | (right >> 1)
 162  
 163  	preOutput := (uint64(right) << 32) | uint64(left)
 164  	byteorder.BEPutUint64(dst, permuteFinalBlock(preOutput))
 165  }
 166