github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/soc/nxp/caam/cipher.go (about)

     1  // NXP Cryptographic Acceleration and Assurance Module (CAAM) driver
     2  // https://github.com/usbarmory/tamago
     3  //
     4  // Copyright (c) WithSecure Corporation
     5  // https://foundry.withsecure.com
     6  //
     7  // Use of this source code is governed by the license
     8  // that can be found in the LICENSE file.
     9  
    10  package caam
    11  
    12  import (
    13  	"crypto/aes"
    14  	"errors"
    15  
    16  	"github.com/usbarmory/tamago/dma"
    17  )
    18  
    19  func (hw *CAAM) cipher(buf []byte, key []byte, iv []byte, mode uint32, enc bool) (err error) {
    20  	if len(buf)%aes.BlockSize != 0 {
    21  		return errors.New("invalid input size")
    22  	}
    23  
    24  	switch len(key) {
    25  	case 16, 24, 32:
    26  		break
    27  	default:
    28  		return aes.KeySizeError(len(key))
    29  	}
    30  
    31  	if len(iv) != aes.BlockSize {
    32  		return errors.New("invalid IV size")
    33  	}
    34  
    35  	keyBufferAddress := dma.Alloc(key, 4)
    36  	defer dma.Free(keyBufferAddress)
    37  
    38  	loadKey := Key{}
    39  	loadKey.SetDefaults()
    40  	loadKey.Class(1)
    41  	loadKey.Pointer(keyBufferAddress, len(key))
    42  
    43  	ivBufferAddress := dma.Alloc(iv, 4)
    44  	defer dma.Free(ivBufferAddress)
    45  
    46  	loadIV := Load{}
    47  	loadIV.SetDefaults()
    48  	loadIV.Class(1)
    49  	loadIV.Destination(CTX)
    50  	loadIV.Pointer(ivBufferAddress, len(iv))
    51  
    52  	op := Operation{}
    53  	op.SetDefaults()
    54  	op.OpType(OPTYPE_ALG_CLASS1)
    55  	op.Algorithm(ALG_AES, mode)
    56  	op.State(AS_INITIALIZE | AS_FINALIZE)
    57  	op.Encrypt(enc)
    58  
    59  	sourceBufferAddress := dma.Alloc(buf, 4)
    60  	defer dma.Free(sourceBufferAddress)
    61  
    62  	src := FIFOLoad{}
    63  	src.SetDefaults()
    64  	src.Class(1)
    65  	src.DataType(INPUT_DATA_TYPE_MESSAGE_DATA | INPUT_DATA_TYPE_LC1)
    66  	src.Pointer(sourceBufferAddress, len(buf))
    67  
    68  	dst := FIFOStore{}
    69  	dst.SetDefaults()
    70  	dst.DataType(OUTPUT_DATA_TYPE_MESSAGE_DATA)
    71  	dst.Pointer(sourceBufferAddress, len(buf))
    72  
    73  	jd := loadKey.Bytes()
    74  	jd = append(jd, loadIV.Bytes()...)
    75  	jd = append(jd, op.Bytes()...)
    76  	jd = append(jd, src.Bytes()...)
    77  	jd = append(jd, dst.Bytes()...)
    78  
    79  	if err = hw.job(nil, jd); err != nil {
    80  		return
    81  	}
    82  
    83  	dma.Read(sourceBufferAddress, 0, buf)
    84  
    85  	return
    86  }
    87  
    88  // Encrypt performs in-place buffer encryption using AES-CBC, the key argument
    89  // should be the AES key, either 16, 24, or 32 bytes to select AES-128,
    90  // AES-192, or AES-256.
    91  //
    92  // All argument buffers are copied to reserved buffers in the default DMA
    93  // region, buffers previously created with dma.Reserve() can be used to avoid
    94  // external RAM exposure, when placed in iRAM, as their pointers are directly
    95  // passed to the CAAM without access by the Go runtime.
    96  func (hw *CAAM) Encrypt(buf []byte, key []byte, iv []byte) (err error) {
    97  	return hw.cipher(buf, key, iv, AAI_AES_CBC, true)
    98  }
    99  
   100  // Decrypt performs in-place buffer decryption using AES-CBC, the key argument
   101  // should be the AES key, either 16, 24, or 32 bytes to select AES-128,
   102  // AES-192, or AES-256.
   103  //
   104  // All argument buffers are copied to reserved buffers in the default DMA
   105  // region, buffers previously created with dma.Reserve() can be used to avoid
   106  // external RAM exposure, when placed in iRAM, as their pointers are directly
   107  // passed to the CAAM without access by the Go runtime.
   108  func (hw *CAAM) Decrypt(buf []byte, key []byte, iv []byte) (err error) {
   109  	return hw.cipher(buf, key, iv, AAI_AES_CBC, false)
   110  }