github.com/sentienttechnologies/studio-go-runner@v0.0.0-20201118202441-6d21f2ced8ee/internal/runner/block_crypto.go (about)

     1  // Copyright 2018-2020 (c) Cognizant Digital Business, Evolutionary AI. All rights reserved. Issued under the Apache 2.0 License.
     2  
     3  package runner
     4  
     5  import (
     6  	"crypto/rand"
     7  	"io"
     8  
     9  	"github.com/go-stack/stack"
    10  	"github.com/jjeffery/kv"
    11  
    12  	"golang.org/x/crypto/nacl/secretbox"
    13  )
    14  
    15  // This file contains code to enable the encryption and decryption of larger
    16  // blocks of data than RSA encryption is suited for.  These functions
    17  // allow symetric key encryption on larger blocks of data with the expectation
    18  // that the symmetric key will ne encrypted using an asymmetric RSA and placed
    19  // at the front of a data block or file.
    20  //
    21  // This set of functions use the nacl compatible secretbox implementation to
    22  // encrypt the contents of the payload with the secret key being obtained
    23  // from an RSA encrypted header at the start of the bytes block.
    24  //
    25  // This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html.
    26  //
    27  // This package works using a 32 byte secret key, a 24 byte nonce, and then the payload.
    28  
    29  // EncryptBlock will generate a nonce, and a secret and will encrypted the supplied
    30  // data using the generated key bundling a 24 byte nonce with it returning the key,
    31  // and the encoded data with the nonce prepended to it.
    32  
    33  func EncryptBlock(data []byte) (key [32]byte, enc []byte, err kv.Error) {
    34  	key = [32]byte{}
    35  	if _, errGo := io.ReadFull(rand.Reader, key[:]); errGo != nil {
    36  		return key, nil, kv.Wrap(errGo, "secret could not be generated").With("stack", stack.Trace().TrimRuntime())
    37  	}
    38  
    39  	nonce := [24]byte{}
    40  	if _, errGo := io.ReadFull(rand.Reader, nonce[:]); errGo != nil {
    41  		return key, nil, kv.Wrap(errGo, "nonce could not be generated").With("stack", stack.Trace().TrimRuntime())
    42  	}
    43  
    44  	encrypted := secretbox.Seal(nonce[:], data, &nonce, &key)
    45  
    46  	return key, encrypted, nil
    47  }
    48  
    49  func DecryptBlock(key [32]byte, in []byte) (clear []byte, err kv.Error) {
    50  
    51  	decryptNonce := [24]byte{}
    52  	copy(decryptNonce[:], in[:24])
    53  
    54  	decrypted, ok := secretbox.Open(nil, in[24:], &decryptNonce, &key)
    55  	if !ok {
    56  		return nil, kv.NewError("decryption failure").With("stack", stack.Trace().TrimRuntime())
    57  	}
    58  
    59  	return decrypted, nil
    60  }