aes.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // Copyright (c) 2017 Yawning Angel <yawning at schwanenlied dot me>
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining
  4. // a copy of this software and associated documentation files (the
  5. // "Software"), to deal in the Software without restriction, including
  6. // without limitation the rights to use, copy, modify, merge, publish,
  7. // distribute, sublicense, and/or sell copies of the Software, and to
  8. // permit persons to whom the Software is furnished to do so, subject to
  9. // the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be
  12. // included in all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  18. // BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  19. // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  20. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. // SOFTWARE.
  22. // Package bsaes is a pure-Go bitsliced constant time AES implementation.
  23. package bsaes
  24. import (
  25. "crypto/aes"
  26. "crypto/cipher"
  27. "errors"
  28. "math"
  29. "runtime"
  30. "git.schwanenlied.me/yawning/bsaes.git/ct32"
  31. "git.schwanenlied.me/yawning/bsaes.git/ct64"
  32. )
  33. var (
  34. useCryptoAES = false
  35. ctor = ct64.NewCipher
  36. )
  37. type resetAble interface {
  38. Reset()
  39. }
  40. // NewCipher creates and returns a new cipher.Block. The key argument should
  41. // be the AES key, either 16, 24, or 32 bytes to select AES-128, AES-192, or
  42. // AES-256.
  43. func NewCipher(key []byte) (cipher.Block, error) {
  44. switch len(key) {
  45. case 16, 24, 32:
  46. default:
  47. return nil, errors.New("aes: Invalid key size")
  48. }
  49. if isCryptoAESSafe() {
  50. return aes.NewCipher(key)
  51. }
  52. blk := ctor(key)
  53. r := blk.(resetAble)
  54. runtime.SetFinalizer(r, (resetAble).Reset)
  55. return blk, nil
  56. }
  57. func init() {
  58. // Fucking appengine doesn't have `unsafe`, so derive based off uintptr.
  59. // It's retarded that this isn't a constant in runtime or something.
  60. maxUintptr := uint64(^uintptr(0))
  61. switch maxUintptr {
  62. case math.MaxUint32:
  63. ctor = ct32.NewCipher
  64. case math.MaxUint64:
  65. ctor = ct64.NewCipher
  66. default:
  67. panic("bsaes: unsupported architecture")
  68. }
  69. useCryptoAES = isCryptoAESSafe()
  70. }