How do you properly setup a CAAM job to perform en/de-capsulation of generic data (not secure memory keys)?

cancel
Showing results for 
Search instead for 
Did you mean: 

How do you properly setup a CAAM job to perform en/de-capsulation of generic data (not secure memory keys)?

2,185 Views
awright
Contributor II

I am trying to use the feature of the i.MX6 processor to perform generic protection of data for secure storage in non-volatile memory. This is done by having the i.MX6 convert the data into a red blob (for general data). I found what I believe is a similar question from user fsquestion at https://community.freescale.com/message/340700.  This question is marked as "Assumed Answered", but it was not.  The only response is from Freescale, but is a response about Encrypted Boot (a completely separate topic). fsquestion has posted that they have still not figured out a way to do this, as current examples are limited to using the secure memory operations. This question does not deal with encrypted boot, just the handling en/de-capsulation of red blobs.

===========

I am attempting to wire a Linux driver to present a character interface that provides an IOCTL to allow user space applications to have a synchronous method to provide data to be en/de-capsulated into/out of red blobs and get the result. I am getting an error from the CAAM job, which tells me that something is wrong with the job descriptor:

1073743888

0x04 0x00 0x00 0x00 0x0008   0x0010

                    DESC IDX ERR: Inv. Seq Command

I tried to build up the descriptor using the following function, which is based on blob_encap_desc in sm_store.c, but modified to attempt to make red blobs to/from regular memory (not secure memory). I have not been able to figure out how to modify (or build) a proper CAAM job descriptor to perform the red blob en/de-capsulation.

/*

* Construct a in-memory red blob en/de-capsulation job descriptor

*

* - desc pointer to hold new (to be allocated) pointer to the generated

* descriptor for later use. Calling thread can kfree the

* descriptor after execution.

* - keymod Physical pointer to key modifier (contiguous piece).

* - keymodsz Size of key modifier in bytes (should normally be 8).

* - inbuf Physical pointer of the data to be en/de-capsulated.

* - outbuf Physical pointer (within an accessible secure memory page)

* of the encapsulated output. This needs to be larger than the

* input buffer by 48 bytes when performing encapsulation of the data.

* - inbuflen Size of input buffer, in bytes.

* - auth If nonzero, use AES-CCM for encapsulation, else use ECB

*

* Note: this uses 32-bit pointers at present

* retval: number of bytes in outbuf

*/

#define INITIAL_DESCSZ 16 /* size of tmp buffer for descriptor const. */

static int caam_blob_capsulate_desc(u32 **desc, dma_addr_t keymod, u16 keymodsz,

  bool encap, dma_addr_t inbuf, dma_addr_t outbuf, u16 inbuflen,

  bool auth)

{

  u32 *tdesc, tmpdesc[INITIAL_DESCSZ];

  u16 dsize, idx;

  memset(tmpdesc, 0, INITIAL_DESCSZ * sizeof(u32));

  idx = 1;

  /* Load key modifier */

  tmpdesc[idx++] = CMD_LOAD | LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY |

  ((12 << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK) |

  (keymodsz & LDST_LEN_MASK);

  tmpdesc[idx++] = (u32)keymod;

  if(encap) {

  /* Encapsulate to memory */

  tmpdesc[idx++] = CMD_SEQ_IN_PTR | inbuflen;

  tmpdesc[idx++] = (u32)inbuf;

  }

  /* Compensate for BKEK and MAC tag */

  tmpdesc[idx++] = CMD_SEQ_IN_PTR | (inbuflen + CAAM_BLOB_HDR_SIZE);

  if(encap) {

  /* Encapsulate to memory */

  tmpdesc[idx++] = (u32)outbuf;

  } else {

  tmpdesc[idx++] = (u32)inbuf;

  tmpdesc[idx++] = CMD_SEQ_OUT_PTR | inbuflen;

  tmpdesc[idx++] = (u32)outbuf;

  tmpdesc[idx] = CMD_OPERATION | OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB |

      OP_PCL_BLOB_FMT_NORMAL;

  }

  /* En/De-capsulate to memory */

  tmpdesc[idx] = CMD_OPERATION | OP_PCLID_BLOB | OP_PCL_BLOB_FMT_NORMAL |

  (encap?OP_TYPE_ENCAP_PROTOCOL:OP_TYPE_DECAP_PROTOCOL);

  if (auth)

  tmpdesc[idx] |= OP_PCL_BLOB_EKT;

  idx++;

  tmpdesc[0] = CMD_DESC_HDR | HDR_ONE | (idx & HDR_DESCLEN_MASK);

  dsize = idx * sizeof(u32);

  tdesc = kmalloc(dsize, GFP_KERNEL | GFP_DMA);

  if (tdesc == NULL)

  return 0;

  memcpy(tdesc, tmpdesc, dsize);

  *desc = tdesc;

  return dsize;

}

Tags (3)
11 Replies

443 Views
adnana
Contributor I

What kernel version are you using? Are you running kernel in secure mode?

I am running uboot and kernel in non-secure mode. But CAAM doesn't even

create job or in simple words when i run "openssl" test for CAAM it doesn't use

CAAM driver which it should. cat /proc/crypto says

Name: cbc(aes)

driver: cbc-aes-caam

Is it same on your part?

0 Kudos

443 Views
awright
Contributor II

I am using a the kernel built from a version of the Freescale 3.0.35-4.0.0 source tree. I have not done anything in particular to put the kernel itself into a "secure mode".  The CPU is running signed firmware in an HAB closed configuration though.

My /proc/crypto does not show any of the caam drivers registers in the CryptoAPI. It reports:

# cat /proc/crypto

name        : aes

driver      : aes-generic

module      : aes_generic

priority    : 100

refcnt      : 4

selftest    : passed

type        : cipher

blocksize    : 16

min keysize  : 16

max keysize  : 32

name        : arc4

driver      : arc4-generic

module      : arc4

priority    : 0

refcnt      : 3

selftest    : passed

type        : cipher

blocksize    : 1

min keysize  : 1

max keysize  : 256

name        : stdrng

driver      : krng

module      : kernel

priority    : 200

refcnt      : 1

selftest    : passed

type        : rng

seedsize    : 0

name        : michael_mic

driver      : michael_mic-generic

module      : kernel

priority    : 0

refcnt      : 1

selftest    : passed

type        : shash

blocksize    : 8

digestsize  : 8


I am not sure that should matter for me, as I am not trying to access the CAAM to perform generic data encryption via the CryptoAPI (i.e. openssl or ipsec), but just use the CAAM to protect a master key for use in userspace with software encryption, with the device specific OTPMK.  This is what the red blobs are supposed to do, as I understand the manuals.

0 Kudos

443 Views
jdepedro
Contributor IV

Hi awright,

Did you managed to ensamble a job descriptor for encryption/decryption? Could you share details?

0 Kudos

443 Views
awright
Contributor II

Unfortunately, no, I never got it to work.

0 Kudos

443 Views
jdepedro
Contributor IV

Don't worry, I got it working. I can share details if you are still interested.

443 Views
satyadamarla
Contributor III

Hello Jose,

I am interested in how you got it working. Can you please share it in the thread?

0 Kudos

443 Views
jdepedro
Contributor IV

Sorry for the delay.

I don't remember all the details, but there is a reference implementation in the U-Boot code. The job descriptor can be understood using the Security Reference Manual and then implemented in the Linux driver.

0 Kudos

443 Views
adamr
Contributor I

Hi Jose,

Where is the reference implementation in U-Boot code? Can you share the filename or source?

Thanks

443 Views
jdepedro
Contributor IV

See u-boot.git - Automotive U-Boot Tree , first two functions.

0 Kudos

443 Views
samrusty
Contributor I

Jose, would you mind sharing details on how you got this to work?

Thanks in advance

0 Kudos

443 Views
annguyen
Contributor II

Hello Jose,

Can you share more detail? Thanks!

An.

0 Kudos