CC26xx Driver Library
pka.c File Reference
#include "pka.h"

Macros

#define PKA_MAX_CURVE_SIZE_32_BIT_WORD   12
 
#define PKA_MAX_LEN_IN_32_BIT_WORD   PKA_MAX_CURVE_SIZE_32_BIT_WORD
 
#define PKA_NO_POINTER_REG   0xFF
 
#define NISTP256_PARAM_SIZE_BYTES   32
 

Functions

static uint32_t PKAWritePkaParam (const uint8_t *param, uint32_t paramLength, uint32_t paramOffset, uint32_t ptrRegOffset)
 
static uint32_t PKAWritePkaParamExtraOffset (const uint8_t *param, uint32_t paramLength, uint32_t paramOffset, uint32_t ptrRegOffset)
 
static uint32_t PKAGetBigNumResult (uint8_t *resultBuf, uint32_t *resultLength, uint32_t resultPKAMemAddr)
 
static uint32_t PKAGetBigNumResultRemainder (uint8_t *resultBuf, uint32_t *resultLength, uint32_t resultPKAMemAddr)
 
static uint32_t PKAGetECCResult (uint8_t *curvePointX, uint8_t *curvePointY, uint32_t resultPKAMemAddr, uint32_t length)
 
uint32_t PKAGetOpsStatus (void)
 Gets the PKA operation status. More...
 
uint32_t PKABigNumModStart (const uint8_t *bigNum, uint32_t bigNumLength, const uint8_t *modulus, uint32_t modulusLength, uint32_t *resultPKAMemAddr)
 Starts a big number modulus operation. More...
 
uint32_t PKABigNumModGetResult (uint8_t *resultBuf, uint32_t length, uint32_t resultPKAMemAddr)
 Gets the result of the big number modulus operation. More...
 
uint32_t PKABigNumCmpStart (const uint8_t *bigNum1, const uint8_t *bigNum2, uint32_t length)
 Starts the comparison of two big numbers. More...
 
uint32_t PKABigNumCmpGetResult (void)
 Gets the result of the comparison operation of two big numbers. More...
 
uint32_t PKABigNumInvModStart (const uint8_t *bigNum, uint32_t bigNumLength, const uint8_t *modulus, uint32_t modulusLength, uint32_t *resultPKAMemAddr)
 Starts a big number inverse modulo operation. More...
 
uint32_t PKABigNumInvModGetResult (uint8_t *resultBuf, uint32_t length, uint32_t resultPKAMemAddr)
 Gets the result of the big number inverse modulo operation. More...
 
uint32_t PKABigNumMultiplyStart (const uint8_t *multiplicand, uint32_t multiplicandLength, const uint8_t *multiplier, uint32_t multiplierLength, uint32_t *resultPKAMemAddr)
 Starts the multiplication of two big numbers. More...
 
uint32_t PKABigNumMultGetResult (uint8_t *resultBuf, uint32_t *resultLength, uint32_t resultPKAMemAddr)
 Gets the result of the big number multiplication. More...
 
uint32_t PKABigNumAddStart (const uint8_t *bigNum1, uint32_t bigNum1Length, const uint8_t *bigNum2, uint32_t bigNum2Length, uint32_t *resultPKAMemAddr)
 Starts the addition of two big numbers. More...
 
uint32_t PKABigNumSubGetResult (uint8_t *resultBuf, uint32_t *resultLength, uint32_t resultPKAMemAddr)
 Gets the result of the subtration operation on two big numbers. More...
 
uint32_t PKABigNumSubStart (const uint8_t *minuend, uint32_t minuendLength, const uint8_t *subtrahend, uint32_t subtrahendLength, uint32_t *resultPKAMemAddr)
 Starts the subtration of one big number from another. More...
 
uint32_t PKABigNumAddGetResult (uint8_t *resultBuf, uint32_t *resultLength, uint32_t resultPKAMemAddr)
 Gets the result of the addition operation on two big numbers. More...
 
uint32_t PKAEccMultiplyStart (const uint8_t *scalar, const uint8_t *curvePointX, const uint8_t *curvePointY, const uint8_t *prime, const uint8_t *a, const uint8_t *b, uint32_t length, uint32_t *resultPKAMemAddr)
 Starts ECC multiplication. More...
 
uint32_t PKAEccMultiplyGetResult (uint8_t *curvePointX, uint8_t *curvePointY, uint32_t resultPKAMemAddr, uint32_t length)
 Gets the result of ECC multiplication. More...
 
uint32_t PKAEccAddStart (const uint8_t *curvePoint1X, const uint8_t *curvePoint1Y, const uint8_t *curvePoint2X, const uint8_t *curvePoint2Y, const uint8_t *prime, const uint8_t *a, uint32_t length, uint32_t *resultPKAMemAddr)
 Starts the ECC addition. More...
 
uint32_t PKAEccAddGetResult (uint8_t *curvePointX, uint8_t *curvePointY, uint32_t resultPKAMemAddr, uint32_t length)
 Gets the result of the ECC addition. More...
 

Variables

const PKA_EccPoint NISTP256_generator
 X coordinate of the generator point of the NISTP256 curve. More...
 
const PKA_EccParam256 NISTP256_prime
 Prime of the NISTP256 curve. More...
 
const PKA_EccParam256 NISTP256_a
 a constant of the NISTP256 curve when expressed in short Weierstrass form (y^3 = x^2 + a*x + b). More...
 
const PKA_EccParam256 NISTP256_b
 b constant of the NISTP256 curve when expressed in short Weierstrass form (y^3 = x^2 + a*x + b). More...
 
const PKA_EccParam256 NISTP256_order
 Order of the NISTP256 curve. More...
 

Macro Definition Documentation

#define NISTP256_PARAM_SIZE_BYTES   32
#define PKA_MAX_CURVE_SIZE_32_BIT_WORD   12

Referenced by PKAEccMultiplyStart().

#define PKA_MAX_LEN_IN_32_BIT_WORD   PKA_MAX_CURVE_SIZE_32_BIT_WORD
#define PKA_NO_POINTER_REG   0xFF

Function Documentation

static uint32_t PKAGetBigNumResult ( uint8_t *  resultBuf,
uint32_t *  resultLength,
uint32_t  resultPKAMemAddr 
)
static

Referenced by PKABigNumAddGetResult(), PKABigNumInvModGetResult(), PKABigNumMultGetResult(), and PKABigNumSubGetResult().

276 {
277  uint32_t regMSWOffset;
278  uint32_t lswOffset;
279  uint32_t lengthInWords;
280  uint32_t i;
281  uint32_t *resultWordAlias = (uint32_t *)resultBuf;
282 
283  // Check the arguments.
284  ASSERT(resultBuf);
285  ASSERT((resultPKAMemAddr > PKA_RAM_BASE) &&
286  (resultPKAMemAddr < (PKA_RAM_BASE + PKA_RAM_TOT_BYTE_SIZE)));
287 
288  // Verify that the operation is complete.
289  if (HWREG(PKA_BASE + PKA_O_FUNCTION) & PKA_FUNCTION_RUN) {
291  }
292 
293  // Get the MSW register value.
294  regMSWOffset = HWREG(PKA_BASE + PKA_O_MSW);
295 
296  // Check to make sure that the result vector is not all zeros.
297  if (regMSWOffset & PKA_MSW_RESULT_IS_ZERO_M) {
298  return PKA_STATUS_RESULT_0;
299  }
300 
301  // Get the length of the result
302  regMSWOffset = ((regMSWOffset & PKA_MSW_MSW_ADDRESS_M) + 1);
303  lswOffset = ((resultPKAMemAddr - PKA_RAM_BASE) >> 2);
304  lengthInWords = regMSWOffset - lswOffset;
305 
306  // Check if the provided buffer length is adequate to store the result data.
307  if (*resultLength < lengthInWords * sizeof(uint32_t)) {
309  }
310 
311  // Copy the result into the resultBuf.
312  for (i = 0; i < lengthInWords; i++) {
313  resultWordAlias[i]= HWREG(resultPKAMemAddr + sizeof(uint32_t) * i);
314  }
315 
316  // Zero-out the remainder of the result buffer
317  memset(resultWordAlias + i, 0x00, *resultLength - lengthInWords * sizeof(uint32_t));
318 
319  // Copy the resultant length.
320  *resultLength = lengthInWords * sizeof(uint32_t);
321 
322 
323  return PKA_STATUS_SUCCESS;
324 }
#define PKA_STATUS_BUF_UNDERFLOW
Buffer underflow.
Definition: pka.h:116
#define PKA_STATUS_OPERATION_BUSY
PKA operation is in progress.
Definition: pka.h:121
#define PKA_STATUS_SUCCESS
Success.
Definition: pka.h:113
#define ASSERT(expr)
Definition: debug.h:73
#define PKA_STATUS_RESULT_0
Result is all zeros.
Definition: pka.h:117
static uint32_t PKAGetBigNumResultRemainder ( uint8_t *  resultBuf,
uint32_t *  resultLength,
uint32_t  resultPKAMemAddr 
)
static

Referenced by PKABigNumModGetResult().

327 {
328  uint32_t regMSWVal;
329  uint32_t lengthInWords;
330  uint32_t i;
331  uint32_t *resultWordAlias = (uint32_t *)resultBuf;
332 
333  // Check the arguments.
334  ASSERT(resultBuf);
335  ASSERT((resultPKAMemAddr > PKA_RAM_BASE) &&
336  (resultPKAMemAddr < (PKA_RAM_BASE + PKA_RAM_TOT_BYTE_SIZE)));
337 
338  // Verify that the operation is complete.
339  if (HWREG(PKA_BASE + PKA_O_FUNCTION) & PKA_FUNCTION_RUN) {
341  }
342 
343  // Get the MSW register value.
344  regMSWVal = HWREG(PKA_BASE + PKA_O_DIVMSW);
345 
346  // Check to make sure that the result vector is not all zeros.
347  if (regMSWVal & PKA_DIVMSW_RESULT_IS_ZERO_M) {
348  return PKA_STATUS_RESULT_0;
349  }
350 
351  // Get the length of the result
352  lengthInWords = ((regMSWVal & PKA_DIVMSW_MSW_ADDRESS_M) + 1) - ((resultPKAMemAddr - PKA_RAM_BASE) >> 2);
353 
354  // Check if the provided buffer length is adequate to store the result data.
355  if (*resultLength < lengthInWords * sizeof(uint32_t) ) {
357  }
358 
359  // Copy the result into the resultBuf.
360  for (i = 0; i < lengthInWords; i++) {
361  resultWordAlias[i] = HWREG(resultPKAMemAddr + sizeof(uint32_t) * i);
362  }
363 
364  // Zero-out the remainder of the result buffer
365  memset(resultWordAlias + i, 0x00, *resultLength - lengthInWords * sizeof(uint32_t));
366 
367  // Copy the resultant length.
368  *resultLength = lengthInWords * sizeof(uint32_t);
369 
370 
371  return PKA_STATUS_SUCCESS;
372 }
#define PKA_STATUS_BUF_UNDERFLOW
Buffer underflow.
Definition: pka.h:116
#define PKA_STATUS_OPERATION_BUSY
PKA operation is in progress.
Definition: pka.h:121
#define PKA_STATUS_SUCCESS
Success.
Definition: pka.h:113
#define ASSERT(expr)
Definition: debug.h:73
#define PKA_STATUS_RESULT_0
Result is all zeros.
Definition: pka.h:117
static uint32_t PKAGetECCResult ( uint8_t *  curvePointX,
uint8_t *  curvePointY,
uint32_t  resultPKAMemAddr,
uint32_t  length 
)
static

Referenced by PKAEccAddGetResult(), and PKAEccMultiplyGetResult().

380 {
381  uint32_t i = 0;
382  uint32_t *xWordAlias = (uint32_t *)curvePointX;
383  uint32_t *yWordAlias = (uint32_t *)curvePointY;
384 
385  // Check for the arguments.
386  ASSERT(curvePoint);
387  ASSERT(curvePointX);
388  ASSERT(curvePointY);
389  ASSERT((resultPKAMemAddr > PKA_RAM_BASE) &&
390  (resultPKAMemAddr < (PKA_RAM_BASE + PKA_RAM_TOT_BYTE_SIZE)));
391 
392  // Verify that the operation is completed.
393  if (HWREG(PKA_BASE + PKA_O_FUNCTION) & PKA_FUNCTION_RUN) {
395  }
396 
397  if (HWREG(PKA_BASE + PKA_O_SHIFT)) {
398  return PKA_STATUS_FAILURE;
399  }
400 
401  // Check to make sure that the result vector is not all zeros.
402  if (HWREG(PKA_BASE + PKA_O_MSW) & PKA_MSW_RESULT_IS_ZERO) {
403  return PKA_STATUS_RESULT_0;
404  }
405 
406  // TODO: x[i] no longer indexes by word but by byte -> switch to byte addressed
407 
408  if (curvePointX != NULL) {
409  // Copy the x co-ordinate value of the result from vector D into
410  // the curvePoint.
411  for (i = 0; i < (length / sizeof(uint32_t)); i++) {
412  xWordAlias[i] = HWREG(resultPKAMemAddr + sizeof(uint32_t) * i);
413  }
414  }
415 
416  resultPKAMemAddr += sizeof(uint32_t) * (2 + length / sizeof(uint32_t) + ((length / sizeof(uint32_t) % 2)));
417 
418  if (curvePointY != NULL) {
419  // Copy the y co-ordinate value of the result from vector D into
420  // the curvePoint.
421  for (i = 0; i < (length / sizeof(uint32_t)); i++) {
422  yWordAlias[i] = HWREG(resultPKAMemAddr + sizeof(uint32_t) * i);
423  }
424  }
425 
426 
427  return PKA_STATUS_SUCCESS;
428 }
#define PKA_STATUS_FAILURE
Failure.
Definition: pka.h:114
#define PKA_STATUS_OPERATION_BUSY
PKA operation is in progress.
Definition: pka.h:121
#define PKA_STATUS_SUCCESS
Success.
Definition: pka.h:113
#define ASSERT(expr)
Definition: debug.h:73
#define PKA_STATUS_RESULT_0
Result is all zeros.
Definition: pka.h:117
static uint32_t PKAWritePkaParam ( const uint8_t *  param,
uint32_t  paramLength,
uint32_t  paramOffset,
uint32_t  ptrRegOffset 
)
static

Referenced by PKABigNumAddStart(), PKABigNumCmpStart(), PKABigNumInvModStart(), PKABigNumModStart(), PKABigNumMultiplyStart(), PKABigNumSubStart(), PKAEccMultiplyStart(), and PKAWritePkaParamExtraOffset().

207 {
208  uint32_t i;
209  uint32_t *paramWordAlias = (uint32_t *)param;
210  // Take the floor of paramLength in 32-bit words
211  uint32_t paramLengthInWords = paramLength / sizeof(uint32_t);
212 
213  // Load the number in PKA RAM
214  for (i = 0; i < paramLengthInWords; i++) {
215  HWREG(PKA_RAM_BASE + paramOffset + sizeof(uint32_t) * i) = paramWordAlias[i];
216  }
217 
218  // If the length is not a word-multiple, fill up a temporary word and copy that in
219  // to avoid a bus error. The extra zeros at the end should not matter, as the large
220  // number is little-endian and thus has no effect.
221  // We could have correctly calculated ceiling(paramLength / sizeof(uint32_t)) above.
222  // However, we would not have been able to zero-out the extra few most significant
223  // bytes of the most significant word. That would have resulted in doing maths operations
224  // on whatever follows param in RAM. Not a good situation to be in.
225  if (paramLength % sizeof(uint32_t)) {
226  uint32_t temp = 0;
227  memcpy(&temp, &paramWordAlias[i], paramLength % sizeof(uint32_t));
228 
229  HWREG(PKA_RAM_BASE + paramOffset + sizeof(uint32_t) * i) = temp;
230 
231  // Increment paramLengthInWords since we take the ceiling of length / sizeof(uint32_t)
232  paramLengthInWords++;
233  }
234 
235  // Update the A, B, C, or D pointer with the offset address of the PKA RAM location
236  // where the number will be stored.
237  switch (ptrRegOffset) {
238  case PKA_O_APTR:
239  HWREG(PKA_BASE + PKA_O_APTR) = paramOffset >> 2;
240  HWREG(PKA_BASE + PKA_O_ALENGTH) = paramLengthInWords;
241  break;
242  case PKA_O_BPTR:
243  HWREG(PKA_BASE + PKA_O_BPTR) = paramOffset >> 2;
244  HWREG(PKA_BASE + PKA_O_BLENGTH) = paramLengthInWords;
245  break;
246  case PKA_O_CPTR:
247  HWREG(PKA_BASE + PKA_O_CPTR) = paramOffset >> 2;
248  break;
249  case PKA_O_DPTR:
250  HWREG(PKA_BASE + PKA_O_DPTR) = paramOffset >> 2;
251  break;
252  }
253 
254  // Ensure 8-byte alignment of next parameter.
255  // Returns the offset for the next parameter.
256  return paramOffset + sizeof(uint32_t) * (paramLengthInWords + (paramLengthInWords % 2));
257 }
static uint32_t PKAWritePkaParamExtraOffset ( const uint8_t *  param,
uint32_t  paramLength,
uint32_t  paramOffset,
uint32_t  ptrRegOffset 
)
static

Referenced by PKABigNumModStart(), PKAEccAddStart(), and PKAEccMultiplyStart().

265 {
266  // Ensure 16-byte alignment.
267  return (sizeof(uint32_t) * 2) + PKAWritePkaParam(param, paramLength, paramOffset, ptrRegOffset);
268 }
static uint32_t PKAWritePkaParam(const uint8_t *param, uint32_t paramLength, uint32_t paramOffset, uint32_t ptrRegOffset)
Definition: pka.c:206

Here is the call graph for this function: