keyenc.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  1. package keyenc
  2. import (
  3. "crypto"
  4. "crypto/aes"
  5. "crypto/cipher"
  6. "crypto/ecdsa"
  7. "crypto/rand"
  8. "crypto/rsa"
  9. "crypto/sha1"
  10. "crypto/sha256"
  11. "crypto/sha512"
  12. "crypto/subtle"
  13. "encoding/binary"
  14. "fmt"
  15. "hash"
  16. "io"
  17. "golang.org/x/crypto/curve25519"
  18. "golang.org/x/crypto/pbkdf2"
  19. "github.com/lestrrat-go/jwx/internal/ecutil"
  20. "github.com/lestrrat-go/jwx/jwa"
  21. contentcipher "github.com/lestrrat-go/jwx/jwe/internal/cipher"
  22. "github.com/lestrrat-go/jwx/jwe/internal/concatkdf"
  23. "github.com/lestrrat-go/jwx/jwe/internal/keygen"
  24. "github.com/lestrrat-go/jwx/x25519"
  25. "github.com/pkg/errors"
  26. )
  27. func NewNoop(alg jwa.KeyEncryptionAlgorithm, sharedkey []byte) (*Noop, error) {
  28. return &Noop{
  29. alg: alg,
  30. sharedkey: sharedkey,
  31. }, nil
  32. }
  33. func (kw *Noop) Algorithm() jwa.KeyEncryptionAlgorithm {
  34. return kw.alg
  35. }
  36. func (kw *Noop) SetKeyID(v string) {
  37. kw.keyID = v
  38. }
  39. func (kw *Noop) KeyID() string {
  40. return kw.keyID
  41. }
  42. func (kw *Noop) Encrypt(cek []byte) (keygen.ByteSource, error) {
  43. return keygen.ByteKey(kw.sharedkey), nil
  44. }
  45. // NewAES creates a key-wrap encrypter using AES.
  46. // Although the name suggests otherwise, this does the decryption as well.
  47. func NewAES(alg jwa.KeyEncryptionAlgorithm, sharedkey []byte) (*AES, error) {
  48. return &AES{
  49. alg: alg,
  50. sharedkey: sharedkey,
  51. }, nil
  52. }
  53. // Algorithm returns the key encryption algorithm being used
  54. func (kw *AES) Algorithm() jwa.KeyEncryptionAlgorithm {
  55. return kw.alg
  56. }
  57. func (kw *AES) SetKeyID(v string) {
  58. kw.keyID = v
  59. }
  60. // KeyID returns the key ID associated with this encrypter
  61. func (kw *AES) KeyID() string {
  62. return kw.keyID
  63. }
  64. // Decrypt decrypts the encrypted key using AES key unwrap
  65. func (kw *AES) Decrypt(enckey []byte) ([]byte, error) {
  66. block, err := aes.NewCipher(kw.sharedkey)
  67. if err != nil {
  68. return nil, errors.Wrap(err, "failed to create cipher from shared key")
  69. }
  70. cek, err := Unwrap(block, enckey)
  71. if err != nil {
  72. return nil, errors.Wrap(err, "failed to unwrap data")
  73. }
  74. return cek, nil
  75. }
  76. // KeyEncrypt encrypts the given content encryption key
  77. func (kw *AES) Encrypt(cek []byte) (keygen.ByteSource, error) {
  78. block, err := aes.NewCipher(kw.sharedkey)
  79. if err != nil {
  80. return nil, errors.Wrap(err, "failed to create cipher from shared key")
  81. }
  82. encrypted, err := Wrap(block, cek)
  83. if err != nil {
  84. return nil, errors.Wrap(err, `keywrap: failed to wrap key`)
  85. }
  86. return keygen.ByteKey(encrypted), nil
  87. }
  88. func NewAESGCMEncrypt(alg jwa.KeyEncryptionAlgorithm, sharedkey []byte) (*AESGCMEncrypt, error) {
  89. return &AESGCMEncrypt{
  90. algorithm: alg,
  91. sharedkey: sharedkey,
  92. }, nil
  93. }
  94. func (kw AESGCMEncrypt) Algorithm() jwa.KeyEncryptionAlgorithm {
  95. return kw.algorithm
  96. }
  97. func (kw *AESGCMEncrypt) SetKeyID(v string) {
  98. kw.keyID = v
  99. }
  100. func (kw AESGCMEncrypt) KeyID() string {
  101. return kw.keyID
  102. }
  103. func (kw AESGCMEncrypt) Encrypt(cek []byte) (keygen.ByteSource, error) {
  104. block, err := aes.NewCipher(kw.sharedkey)
  105. if err != nil {
  106. return nil, errors.Wrap(err, "failed to create cipher from shared key")
  107. }
  108. aesgcm, err := cipher.NewGCM(block)
  109. if err != nil {
  110. return nil, errors.Wrap(err, "failed to create gcm from cipher")
  111. }
  112. iv := make([]byte, aesgcm.NonceSize())
  113. _, err = io.ReadFull(rand.Reader, iv)
  114. if err != nil {
  115. return nil, errors.Wrap(err, "failed to get random iv")
  116. }
  117. encrypted := aesgcm.Seal(nil, iv, cek, nil)
  118. tag := encrypted[len(encrypted)-aesgcm.Overhead():]
  119. ciphertext := encrypted[:len(encrypted)-aesgcm.Overhead()]
  120. return keygen.ByteWithIVAndTag{
  121. ByteKey: ciphertext,
  122. IV: iv,
  123. Tag: tag,
  124. }, nil
  125. }
  126. func NewPBES2Encrypt(alg jwa.KeyEncryptionAlgorithm, password []byte) (*PBES2Encrypt, error) {
  127. var hashFunc func() hash.Hash
  128. var keylen int
  129. switch alg {
  130. case jwa.PBES2_HS256_A128KW:
  131. hashFunc = sha256.New
  132. keylen = 16
  133. case jwa.PBES2_HS384_A192KW:
  134. hashFunc = sha512.New384
  135. keylen = 24
  136. case jwa.PBES2_HS512_A256KW:
  137. hashFunc = sha512.New
  138. keylen = 32
  139. default:
  140. return nil, errors.Errorf("unexpected key encryption algorithm %s", alg)
  141. }
  142. return &PBES2Encrypt{
  143. algorithm: alg,
  144. password: password,
  145. hashFunc: hashFunc,
  146. keylen: keylen,
  147. }, nil
  148. }
  149. func (kw PBES2Encrypt) Algorithm() jwa.KeyEncryptionAlgorithm {
  150. return kw.algorithm
  151. }
  152. func (kw *PBES2Encrypt) SetKeyID(v string) {
  153. kw.keyID = v
  154. }
  155. func (kw PBES2Encrypt) KeyID() string {
  156. return kw.keyID
  157. }
  158. func (kw PBES2Encrypt) Encrypt(cek []byte) (keygen.ByteSource, error) {
  159. count := 10000
  160. salt := make([]byte, kw.keylen)
  161. _, err := io.ReadFull(rand.Reader, salt)
  162. if err != nil {
  163. return nil, errors.Wrap(err, "failed to get random salt")
  164. }
  165. fullsalt := []byte(kw.algorithm)
  166. fullsalt = append(fullsalt, byte(0))
  167. fullsalt = append(fullsalt, salt...)
  168. sharedkey := pbkdf2.Key(kw.password, fullsalt, count, kw.keylen, kw.hashFunc)
  169. block, err := aes.NewCipher(sharedkey)
  170. if err != nil {
  171. return nil, errors.Wrap(err, "failed to create cipher from shared key")
  172. }
  173. encrypted, err := Wrap(block, cek)
  174. if err != nil {
  175. return nil, errors.Wrap(err, `keywrap: failed to wrap key`)
  176. }
  177. return keygen.ByteWithSaltAndCount{
  178. ByteKey: encrypted,
  179. Salt: salt,
  180. Count: count,
  181. }, nil
  182. }
  183. // NewECDHESEncrypt creates a new key encrypter based on ECDH-ES
  184. func NewECDHESEncrypt(alg jwa.KeyEncryptionAlgorithm, enc jwa.ContentEncryptionAlgorithm, keysize int, keyif interface{}) (*ECDHESEncrypt, error) {
  185. var generator keygen.Generator
  186. var err error
  187. switch key := keyif.(type) {
  188. case *ecdsa.PublicKey:
  189. generator, err = keygen.NewEcdhes(alg, enc, keysize, key)
  190. case x25519.PublicKey:
  191. generator, err = keygen.NewX25519(alg, enc, keysize, key)
  192. default:
  193. return nil, errors.Errorf("unexpected key type %T", keyif)
  194. }
  195. if err != nil {
  196. return nil, errors.Wrap(err, "failed to create key generator")
  197. }
  198. return &ECDHESEncrypt{
  199. algorithm: alg,
  200. generator: generator,
  201. }, nil
  202. }
  203. // Algorithm returns the key encryption algorithm being used
  204. func (kw ECDHESEncrypt) Algorithm() jwa.KeyEncryptionAlgorithm {
  205. return kw.algorithm
  206. }
  207. func (kw *ECDHESEncrypt) SetKeyID(v string) {
  208. kw.keyID = v
  209. }
  210. // KeyID returns the key ID associated with this encrypter
  211. func (kw ECDHESEncrypt) KeyID() string {
  212. return kw.keyID
  213. }
  214. // KeyEncrypt encrypts the content encryption key using ECDH-ES
  215. func (kw ECDHESEncrypt) Encrypt(cek []byte) (keygen.ByteSource, error) {
  216. kg, err := kw.generator.Generate()
  217. if err != nil {
  218. return nil, errors.Wrap(err, "failed to create key generator")
  219. }
  220. bwpk, ok := kg.(keygen.ByteWithECPublicKey)
  221. if !ok {
  222. return nil, errors.New("key generator generated invalid key (expected ByteWithECPrivateKey)")
  223. }
  224. if kw.algorithm == jwa.ECDH_ES {
  225. return bwpk, nil
  226. }
  227. block, err := aes.NewCipher(bwpk.Bytes())
  228. if err != nil {
  229. return nil, errors.Wrap(err, "failed to generate cipher from generated key")
  230. }
  231. jek, err := Wrap(block, cek)
  232. if err != nil {
  233. return nil, errors.Wrap(err, "failed to wrap data")
  234. }
  235. bwpk.ByteKey = keygen.ByteKey(jek)
  236. return bwpk, nil
  237. }
  238. // NewECDHESDecrypt creates a new key decrypter using ECDH-ES
  239. func NewECDHESDecrypt(keyalg jwa.KeyEncryptionAlgorithm, contentalg jwa.ContentEncryptionAlgorithm, pubkey interface{}, apu, apv []byte, privkey interface{}) *ECDHESDecrypt {
  240. return &ECDHESDecrypt{
  241. keyalg: keyalg,
  242. contentalg: contentalg,
  243. apu: apu,
  244. apv: apv,
  245. privkey: privkey,
  246. pubkey: pubkey,
  247. }
  248. }
  249. // Algorithm returns the key encryption algorithm being used
  250. func (kw ECDHESDecrypt) Algorithm() jwa.KeyEncryptionAlgorithm {
  251. return kw.keyalg
  252. }
  253. func DeriveZ(privkeyif interface{}, pubkeyif interface{}) ([]byte, error) {
  254. switch privkeyif.(type) {
  255. case x25519.PrivateKey:
  256. privkey, ok := privkeyif.(x25519.PrivateKey)
  257. if !ok {
  258. return nil, errors.Errorf(`private key must be x25519.PrivateKey, was: %T`, privkeyif)
  259. }
  260. pubkey, ok := pubkeyif.(x25519.PublicKey)
  261. if !ok {
  262. return nil, errors.Errorf(`public key must be x25519.PublicKey, was: %T`, pubkeyif)
  263. }
  264. return curve25519.X25519(privkey.Seed(), pubkey)
  265. default:
  266. privkey, ok := privkeyif.(*ecdsa.PrivateKey)
  267. if !ok {
  268. return nil, errors.Errorf(`private key must be *ecdsa.PrivateKey, was: %T`, privkeyif)
  269. }
  270. pubkey, ok := pubkeyif.(*ecdsa.PublicKey)
  271. if !ok {
  272. return nil, errors.Errorf(`public key must be *ecdsa.PublicKey, was: %T`, pubkeyif)
  273. }
  274. if !privkey.PublicKey.Curve.IsOnCurve(pubkey.X, pubkey.Y) {
  275. return nil, errors.New(`public key must be on the same curve as private key`)
  276. }
  277. z, _ := privkey.PublicKey.Curve.ScalarMult(pubkey.X, pubkey.Y, privkey.D.Bytes())
  278. zBytes := ecutil.AllocECPointBuffer(z, privkey.Curve)
  279. defer ecutil.ReleaseECPointBuffer(zBytes)
  280. zCopy := make([]byte, len(zBytes))
  281. copy(zCopy, zBytes)
  282. return zCopy, nil
  283. }
  284. }
  285. func DeriveECDHES(alg, apu, apv []byte, privkey interface{}, pubkey interface{}, keysize uint32) ([]byte, error) {
  286. pubinfo := make([]byte, 4)
  287. binary.BigEndian.PutUint32(pubinfo, keysize*8)
  288. zBytes, err := DeriveZ(privkey, pubkey)
  289. if err != nil {
  290. return nil, errors.Wrap(err, "unable to determine Z")
  291. }
  292. kdf := concatkdf.New(crypto.SHA256, alg, zBytes, apu, apv, pubinfo, []byte{})
  293. key := make([]byte, keysize)
  294. if _, err := kdf.Read(key); err != nil {
  295. return nil, errors.Wrap(err, "failed to read kdf")
  296. }
  297. return key, nil
  298. }
  299. // Decrypt decrypts the encrypted key using ECDH-ES
  300. func (kw ECDHESDecrypt) Decrypt(enckey []byte) ([]byte, error) {
  301. var algBytes []byte
  302. var keysize uint32
  303. // Use keyalg except for when jwa.ECDH_ES
  304. algBytes = []byte(kw.keyalg.String())
  305. switch kw.keyalg {
  306. case jwa.ECDH_ES:
  307. // Create a content cipher from the content encryption algorithm
  308. c, err := contentcipher.NewAES(kw.contentalg)
  309. if err != nil {
  310. return nil, errors.Wrapf(err, `failed to create content cipher for %s`, kw.contentalg)
  311. }
  312. keysize = uint32(c.KeySize())
  313. algBytes = []byte(kw.contentalg.String())
  314. case jwa.ECDH_ES_A128KW:
  315. keysize = 16
  316. case jwa.ECDH_ES_A192KW:
  317. keysize = 24
  318. case jwa.ECDH_ES_A256KW:
  319. keysize = 32
  320. default:
  321. return nil, errors.Errorf("invalid ECDH-ES key wrap algorithm (%s)", kw.keyalg)
  322. }
  323. key, err := DeriveECDHES(algBytes, kw.apu, kw.apv, kw.privkey, kw.pubkey, keysize)
  324. if err != nil {
  325. return nil, errors.Wrap(err, `failed to derive ECDHES encryption key`)
  326. }
  327. // ECDH-ES does not wrap keys
  328. if kw.keyalg == jwa.ECDH_ES {
  329. return key, nil
  330. }
  331. block, err := aes.NewCipher(key)
  332. if err != nil {
  333. return nil, errors.Wrap(err, "failed to create cipher for ECDH-ES key wrap")
  334. }
  335. return Unwrap(block, enckey)
  336. }
  337. // NewRSAOAEPEncrypt creates a new key encrypter using RSA OAEP
  338. func NewRSAOAEPEncrypt(alg jwa.KeyEncryptionAlgorithm, pubkey *rsa.PublicKey) (*RSAOAEPEncrypt, error) {
  339. switch alg {
  340. case jwa.RSA_OAEP, jwa.RSA_OAEP_256:
  341. default:
  342. return nil, errors.Errorf("invalid RSA OAEP encrypt algorithm (%s)", alg)
  343. }
  344. return &RSAOAEPEncrypt{
  345. alg: alg,
  346. pubkey: pubkey,
  347. }, nil
  348. }
  349. // NewRSAPKCSEncrypt creates a new key encrypter using PKCS1v15
  350. func NewRSAPKCSEncrypt(alg jwa.KeyEncryptionAlgorithm, pubkey *rsa.PublicKey) (*RSAPKCSEncrypt, error) {
  351. switch alg {
  352. case jwa.RSA1_5:
  353. default:
  354. return nil, errors.Errorf("invalid RSA PKCS encrypt algorithm (%s)", alg)
  355. }
  356. return &RSAPKCSEncrypt{
  357. alg: alg,
  358. pubkey: pubkey,
  359. }, nil
  360. }
  361. // Algorithm returns the key encryption algorithm being used
  362. func (e RSAPKCSEncrypt) Algorithm() jwa.KeyEncryptionAlgorithm {
  363. return e.alg
  364. }
  365. func (e *RSAPKCSEncrypt) SetKeyID(v string) {
  366. e.keyID = v
  367. }
  368. // KeyID returns the key ID associated with this encrypter
  369. func (e RSAPKCSEncrypt) KeyID() string {
  370. return e.keyID
  371. }
  372. // Algorithm returns the key encryption algorithm being used
  373. func (e RSAOAEPEncrypt) Algorithm() jwa.KeyEncryptionAlgorithm {
  374. return e.alg
  375. }
  376. func (e *RSAOAEPEncrypt) SetKeyID(v string) {
  377. e.keyID = v
  378. }
  379. // KeyID returns the key ID associated with this encrypter
  380. func (e RSAOAEPEncrypt) KeyID() string {
  381. return e.keyID
  382. }
  383. // KeyEncrypt encrypts the content encryption key using RSA PKCS1v15
  384. func (e RSAPKCSEncrypt) Encrypt(cek []byte) (keygen.ByteSource, error) {
  385. if e.alg != jwa.RSA1_5 {
  386. return nil, errors.Errorf("invalid RSA PKCS encrypt algorithm (%s)", e.alg)
  387. }
  388. encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, e.pubkey, cek)
  389. if err != nil {
  390. return nil, errors.Wrap(err, "failed to encrypt using PKCS1v15")
  391. }
  392. return keygen.ByteKey(encrypted), nil
  393. }
  394. // KeyEncrypt encrypts the content encryption key using RSA OAEP
  395. func (e RSAOAEPEncrypt) Encrypt(cek []byte) (keygen.ByteSource, error) {
  396. var hash hash.Hash
  397. switch e.alg {
  398. case jwa.RSA_OAEP:
  399. hash = sha1.New()
  400. case jwa.RSA_OAEP_256:
  401. hash = sha256.New()
  402. default:
  403. return nil, errors.New("failed to generate key encrypter for RSA-OAEP: RSA_OAEP/RSA_OAEP_256 required")
  404. }
  405. encrypted, err := rsa.EncryptOAEP(hash, rand.Reader, e.pubkey, cek, []byte{})
  406. if err != nil {
  407. return nil, errors.Wrap(err, `failed to OAEP encrypt`)
  408. }
  409. return keygen.ByteKey(encrypted), nil
  410. }
  411. // NewRSAPKCS15Decrypt creates a new decrypter using RSA PKCS1v15
  412. func NewRSAPKCS15Decrypt(alg jwa.KeyEncryptionAlgorithm, privkey *rsa.PrivateKey, keysize int) *RSAPKCS15Decrypt {
  413. generator := keygen.NewRandom(keysize * 2)
  414. return &RSAPKCS15Decrypt{
  415. alg: alg,
  416. privkey: privkey,
  417. generator: generator,
  418. }
  419. }
  420. // Algorithm returns the key encryption algorithm being used
  421. func (d RSAPKCS15Decrypt) Algorithm() jwa.KeyEncryptionAlgorithm {
  422. return d.alg
  423. }
  424. // Decrypt decrypts the encrypted key using RSA PKCS1v1.5
  425. func (d RSAPKCS15Decrypt) Decrypt(enckey []byte) ([]byte, error) {
  426. // Hey, these notes and workarounds were stolen from go-jose
  427. defer func() {
  428. // DecryptPKCS1v15SessionKey sometimes panics on an invalid payload
  429. // because of an index out of bounds error, which we want to ignore.
  430. // This has been fixed in Go 1.3.1 (released 2014/08/13), the recover()
  431. // only exists for preventing crashes with unpatched versions.
  432. // See: https://groups.google.com/forum/#!topic/golang-dev/7ihX6Y6kx9k
  433. // See: https://code.google.com/p/go/source/detail?r=58ee390ff31602edb66af41ed10901ec95904d33
  434. _ = recover()
  435. }()
  436. // Perform some input validation.
  437. expectedlen := d.privkey.PublicKey.N.BitLen() / 8
  438. if expectedlen != len(enckey) {
  439. // Input size is incorrect, the encrypted payload should always match
  440. // the size of the public modulus (e.g. using a 2048 bit key will
  441. // produce 256 bytes of output). Reject this since it's invalid input.
  442. return nil, fmt.Errorf(
  443. "input size for key decrypt is incorrect (expected %d, got %d)",
  444. expectedlen,
  445. len(enckey),
  446. )
  447. }
  448. var err error
  449. bk, err := d.generator.Generate()
  450. if err != nil {
  451. return nil, errors.New("failed to generate key")
  452. }
  453. cek := bk.Bytes()
  454. // When decrypting an RSA-PKCS1v1.5 payload, we must take precautions to
  455. // prevent chosen-ciphertext attacks as described in RFC 3218, "Preventing
  456. // the Million Message Attack on Cryptographic Message Syntax". We are
  457. // therefore deliberately ignoring errors here.
  458. err = rsa.DecryptPKCS1v15SessionKey(rand.Reader, d.privkey, enckey, cek)
  459. if err != nil {
  460. return nil, errors.Wrap(err, "failed to decrypt via PKCS1v15")
  461. }
  462. return cek, nil
  463. }
  464. // NewRSAOAEPDecrypt creates a new key decrypter using RSA OAEP
  465. func NewRSAOAEPDecrypt(alg jwa.KeyEncryptionAlgorithm, privkey *rsa.PrivateKey) (*RSAOAEPDecrypt, error) {
  466. switch alg {
  467. case jwa.RSA_OAEP, jwa.RSA_OAEP_256:
  468. default:
  469. return nil, errors.Errorf("invalid RSA OAEP decrypt algorithm (%s)", alg)
  470. }
  471. return &RSAOAEPDecrypt{
  472. alg: alg,
  473. privkey: privkey,
  474. }, nil
  475. }
  476. // Algorithm returns the key encryption algorithm being used
  477. func (d RSAOAEPDecrypt) Algorithm() jwa.KeyEncryptionAlgorithm {
  478. return d.alg
  479. }
  480. // Decrypt decrypts the encrypted key using RSA OAEP
  481. func (d RSAOAEPDecrypt) Decrypt(enckey []byte) ([]byte, error) {
  482. var hash hash.Hash
  483. switch d.alg {
  484. case jwa.RSA_OAEP:
  485. hash = sha1.New()
  486. case jwa.RSA_OAEP_256:
  487. hash = sha256.New()
  488. default:
  489. return nil, errors.New("failed to generate key encrypter for RSA-OAEP: RSA_OAEP/RSA_OAEP_256 required")
  490. }
  491. return rsa.DecryptOAEP(hash, rand.Reader, d.privkey, enckey, []byte{})
  492. }
  493. // Decrypt for DirectDecrypt does not do anything other than
  494. // return a copy of the embedded key
  495. func (d DirectDecrypt) Decrypt() ([]byte, error) {
  496. cek := make([]byte, len(d.Key))
  497. copy(cek, d.Key)
  498. return cek, nil
  499. }
  500. var keywrapDefaultIV = []byte{0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6}
  501. const keywrapChunkLen = 8
  502. func Wrap(kek cipher.Block, cek []byte) ([]byte, error) {
  503. if len(cek)%8 != 0 {
  504. return nil, errors.New(`keywrap input must be 8 byte blocks`)
  505. }
  506. n := len(cek) / keywrapChunkLen
  507. r := make([][]byte, n)
  508. for i := 0; i < n; i++ {
  509. r[i] = make([]byte, keywrapChunkLen)
  510. copy(r[i], cek[i*keywrapChunkLen:])
  511. }
  512. buffer := make([]byte, keywrapChunkLen*2)
  513. tBytes := make([]byte, keywrapChunkLen)
  514. copy(buffer, keywrapDefaultIV)
  515. for t := 0; t < 6*n; t++ {
  516. copy(buffer[keywrapChunkLen:], r[t%n])
  517. kek.Encrypt(buffer, buffer)
  518. binary.BigEndian.PutUint64(tBytes, uint64(t+1))
  519. for i := 0; i < keywrapChunkLen; i++ {
  520. buffer[i] = buffer[i] ^ tBytes[i]
  521. }
  522. copy(r[t%n], buffer[keywrapChunkLen:])
  523. }
  524. out := make([]byte, (n+1)*keywrapChunkLen)
  525. copy(out, buffer[:keywrapChunkLen])
  526. for i := range r {
  527. copy(out[(i+1)*8:], r[i])
  528. }
  529. return out, nil
  530. }
  531. func Unwrap(block cipher.Block, ciphertxt []byte) ([]byte, error) {
  532. if len(ciphertxt)%keywrapChunkLen != 0 {
  533. return nil, errors.Errorf(`keyunwrap input must be %d byte blocks`, keywrapChunkLen)
  534. }
  535. n := (len(ciphertxt) / keywrapChunkLen) - 1
  536. r := make([][]byte, n)
  537. for i := range r {
  538. r[i] = make([]byte, keywrapChunkLen)
  539. copy(r[i], ciphertxt[(i+1)*keywrapChunkLen:])
  540. }
  541. buffer := make([]byte, keywrapChunkLen*2)
  542. tBytes := make([]byte, keywrapChunkLen)
  543. copy(buffer[:keywrapChunkLen], ciphertxt[:keywrapChunkLen])
  544. for t := 6*n - 1; t >= 0; t-- {
  545. binary.BigEndian.PutUint64(tBytes, uint64(t+1))
  546. for i := 0; i < keywrapChunkLen; i++ {
  547. buffer[i] = buffer[i] ^ tBytes[i]
  548. }
  549. copy(buffer[keywrapChunkLen:], r[t%n])
  550. block.Decrypt(buffer, buffer)
  551. copy(r[t%n], buffer[keywrapChunkLen:])
  552. }
  553. if subtle.ConstantTimeCompare(buffer[:keywrapChunkLen], keywrapDefaultIV) == 0 {
  554. return nil, errors.New("key unwrap: failed to unwrap key")
  555. }
  556. out := make([]byte, n*keywrapChunkLen)
  557. for i := range r {
  558. copy(out[i*keywrapChunkLen:], r[i])
  559. }
  560. return out, nil
  561. }