func (alg *AesGcm) Encrypt(aad, plainText, cek []byte) (iv, cipherText, authTag []byte, err error) { cekSizeBits := len(cek) << 3 if cekSizeBits != alg.keySizeBits { return nil, nil, nil, errors.New(fmt.Sprintf("AesGcm.Encrypt(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, cekSizeBits)) } if iv, err = arrays.Random(12); err != nil { return nil, nil, nil, err } var block cipher.Block if block, err = aes.NewCipher(cek); err != nil { return nil, nil, nil, err } var aesgcm cipher.AEAD if aesgcm, err = cipher.NewGCM(block); err != nil { return nil, nil, nil, err } cipherWithTag := aesgcm.Seal(nil, iv, plainText, aad) cipherText = cipherWithTag[:len(cipherWithTag)-aesgcm.Overhead()] authTag = cipherWithTag[len(cipherWithTag)-aesgcm.Overhead():] return iv, cipherText, authTag, nil }
// encrypt is used to encrypt a value func (b *AESGCMBarrier) encrypt(path string, term uint32, gcm cipher.AEAD, plain []byte) []byte { // Allocate the output buffer with room for tern, version byte, // nonce, GCM tag and the plaintext capacity := termSize + 1 + gcm.NonceSize() + gcm.Overhead() + len(plain) size := termSize + 1 + gcm.NonceSize() out := make([]byte, size, capacity) // Set the key term binary.BigEndian.PutUint32(out[:4], term) // Set the version byte out[4] = b.currentAESGCMVersionByte // Generate a random nonce nonce := out[5 : 5+gcm.NonceSize()] rand.Read(nonce) // Seal the output switch b.currentAESGCMVersionByte { case AESGCMVersion1: out = gcm.Seal(out, nonce, plain, nil) case AESGCMVersion2: out = gcm.Seal(out, nonce, plain, []byte(path)) default: panic("Unknown AESGCM version") } return out }
func (alg *AesGcmKW) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { if kek, ok := key.([]byte); ok { kekSizeBits := len(kek) << 3 if kekSizeBits != alg.keySizeBits { return nil, nil, errors.New(fmt.Sprintf("AesGcmKW.WrapNewKey(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, kekSizeBits)) } if cek, err = arrays.Random(cekSizeBits >> 3); err != nil { return nil, nil, err } var iv []byte if iv, err = arrays.Random(12); err != nil { return nil, nil, err } var block cipher.Block if block, err = aes.NewCipher(kek); err != nil { return nil, nil, err } var aesgcm cipher.AEAD if aesgcm, err = cipher.NewGCM(block); err != nil { return nil, nil, err } cipherWithTag := aesgcm.Seal(nil, iv, cek, nil) cipherText := cipherWithTag[:len(cipherWithTag)-aesgcm.Overhead()] authTag := cipherWithTag[len(cipherWithTag)-aesgcm.Overhead():] header["iv"] = base64url.Encode(iv) header["tag"] = base64url.Encode(authTag) return cek, cipherText, nil } return nil, nil, errors.New("AesGcmKW.WrapNewKey(): expected key to be '[]byte' array") }
// encrypt is used to encrypt a value func (b *AESGCMBarrier) encrypt(term uint32, gcm cipher.AEAD, plain []byte) []byte { // Allocate the output buffer with room for tern, version byte, // nonce, GCM tag and the plaintext capacity := termSize + 1 + gcm.NonceSize() + gcm.Overhead() + len(plain) size := termSize + 1 + gcm.NonceSize() out := make([]byte, size, capacity) // Set the key term binary.BigEndian.PutUint32(out[:4], term) // Set the version byte out[4] = aesgcmVersionByte // Generate a random nonce nonce := out[5 : 5+gcm.NonceSize()] rand.Read(nonce) // Seal the output out = gcm.Seal(out, nonce, plain, nil) return out }
// encrypt is used to encrypt a value func (b *AESGCMBarrier) encrypt(gcm cipher.AEAD, plain []byte) []byte { // Allocate the output buffer with room for epoch, version byte, // nonce, GCM tag and the plaintext capacity := epochSize + 1 + gcm.NonceSize() + gcm.Overhead() + len(plain) size := epochSize + 1 + gcm.NonceSize() out := make([]byte, size, capacity) // Set the epoch to 1 out[3] = keyEpoch // Set the version byte out[4] = aesgcmVersionByte // Generate a random nonce nonce := out[5 : 5+gcm.NonceSize()] rand.Read(nonce) // Seal the output out = gcm.Seal(out, nonce, plain, nil) return out }