github.com/lestrrat-go/jwx/v2@v2.0.21/jwe/internal/keyenc/keyenc.go (about)

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