mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-29 18:11:05 +00:00
The utility builds on the extended command protocol recently introduced in the EC and allows to test implementation of various cryptographic primitives available on CR50. This patch brings in the ftdi_spi_tpm.c and mpsse.c from the AOSP trunksd package. mpsse.c has been modified to limit its feature set (no i2c or bigbang support, only SPI0 mode), and ftdit_spi_tpm.c has been modified to properly present binary strings to the Python swig wrapper. The crypro_test.xml file includes descriptions of the tests to perform on the target. Most of its contents other than the first crypto_test element are borrowed from NIST AES test vectors set. See file header for description of the contents format. The actual test command is the tpmtest.py. When started it establishes connection with the device, and then reads test vectors from crypto_test.xml and executes them one at a time. Starting the test program with the -d command line argument enables debug output sent to the console. There are some other programs in ./extras which use the mpsse.c from AOSP, they will have to be modified to use the local copy. BRANCH=none BUG=chrome-os-partner:43025 TEST=ran the following in the directory: $ make # output suppressed $ ./tpmtest.py Starting MPSSE at 800 kHz Connected to device vid:did:rid of 1ae0:0028:00 \New max timeout: 1 s SUCCESS: AES:ECB common SUCCESS: AES:ECB128 1 SUCCESS: AES:ECB192 1 SUCCESS: AES:ECB256 1 SUCCESS: AES:ECB256 2 SUCCESS: AES:CTR128I 1 SUCCESS: AES:CTR256I 1 - temporarily corrupted the contents of the clear_text element of 'AES:ECB common': $ ./tpmtest.py Starting MPSSE at 800 kHz Connected to device vid:did:rid of 1ae0:0028:00 | Out text mismatch in node AES:ECB common, operation 1: In text: 74 68 69 73 20 20 69 73 20 74 68 65 20 74 65 78 74 20 77 68 69 63 68 20 77 69 6c 6c 20 62 65 20 65 6e 63 72 79 70 74 65 64 20 69 66 20 65 76 65 72 79 74 68 69 6e 67 20 69 73 20 67 6f 69 6e 67 20 66 69 6e 65 2e 20 Expected out text: 3d e2 0f f9 ee d9 62 ce f0 8a 17 57 c6 04 86 d0 3d ec 44 72 d8 79 18 87 3f 31 81 6d 66 4c bb 10 da 8d e0 9f 63 67 b3 cc 64 b4 e8 bd 12 b0 a9 c9 09 6d f0 9f a4 e2 ae fb 0d fe 1c 90 6c e2 fe f0 68 8f b5 34 07 76 e2 a9 72 8e dd 7b 8b 52 2b 8b Real out text: f9 50 fe 93 c9 3f cb e5 9e e0 a4 7e 51 1a bb a0 36 2f d1 d6 5f a8 1d 22 5a 1a bb f7 e6 65 89 55 ad e8 f5 8f 1a 20 ff a5 c4 de 76 3e b8 ef cc 8d 9d 94 b8 89 22 1c c9 2a 43 58 c3 8c 75 9f 9f 56 ab 2f 89 1a f6 a0 36 8b 95 23 91 d6 23 47 77 36 Change-Id: I2687ac03236b528e71b92df7cb35606e473ab2c5 Signed-off-by: Vadim Bendebury <vbendeb@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/313443 Reviewed-by: Bill Richardson <wfrichar@chromium.org>
219 lines
4.7 KiB
C
219 lines
4.7 KiB
C
/* Copyright 2015 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*
|
|
* Based on Craig Heffner's version of Dec 27 2011, published on
|
|
* https://github.com/devttys0/libmpsse
|
|
*
|
|
* Internal functions used by libmpsse.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#if LIBFTDI1 == 1
|
|
#include <libftdi1/ftdi.h>
|
|
#else
|
|
#include <ftdi.h>
|
|
#endif
|
|
|
|
#include "support.h"
|
|
|
|
/* Write data to the FTDI chip */
|
|
int raw_write(struct mpsse_context *mpsse, unsigned char *buf, int size)
|
|
{
|
|
int retval = MPSSE_FAIL;
|
|
|
|
if (mpsse->mode && (ftdi_write_data(&mpsse->ftdi, buf, size) == size))
|
|
retval = MPSSE_OK;
|
|
|
|
return retval;
|
|
}
|
|
|
|
/* Read data from the FTDI chip */
|
|
int raw_read(struct mpsse_context *mpsse, unsigned char *buf, int size)
|
|
{
|
|
int n = 0, r = 0;
|
|
|
|
if (!mpsse->mode)
|
|
return 0;
|
|
|
|
while (n < size) {
|
|
r = ftdi_read_data(&mpsse->ftdi, buf, size);
|
|
if (r < 0)
|
|
break;
|
|
n += r;
|
|
}
|
|
|
|
if (mpsse->flush_after_read) {
|
|
/*
|
|
* Make sure the buffers are cleared after a read or
|
|
* subsequent reads may fail. Is this needed anymore?
|
|
* It slows down repetitive read operations by ~8%.
|
|
*/
|
|
ftdi_usb_purge_rx_buffer(&mpsse->ftdi);
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
/* Sets the read and write timeout periods for bulk usb data transfers. */
|
|
void set_timeouts(struct mpsse_context *mpsse, int timeout)
|
|
{
|
|
if (mpsse->mode) {
|
|
mpsse->ftdi.usb_read_timeout = timeout;
|
|
mpsse->ftdi.usb_write_timeout = timeout;
|
|
}
|
|
}
|
|
|
|
/* Convert a frequency to a clock divisor */
|
|
uint16_t freq2div(uint32_t system_clock, uint32_t freq)
|
|
{
|
|
return (((system_clock / freq) / 2) - 1);
|
|
}
|
|
|
|
/* Convert a clock divisor to a frequency */
|
|
uint32_t div2freq(uint32_t system_clock, uint16_t div)
|
|
{
|
|
return (system_clock / ((1 + div) * 2));
|
|
}
|
|
|
|
/* Builds a buffer of commands + data blocks */
|
|
unsigned char *build_block_buffer(struct mpsse_context *mpsse,
|
|
uint8_t cmd,
|
|
unsigned char *data, int size, int *buf_size)
|
|
{
|
|
unsigned char *buf = NULL;
|
|
int i = 0, j = 0, k = 0, dsize = 0, num_blocks = 0, total_size =
|
|
0, xfer_size = 0;
|
|
uint16_t rsize = 0;
|
|
|
|
*buf_size = 0;
|
|
|
|
/* Data block size is 1 in I2C, or when in bitmode */
|
|
if (mpsse->mode == I2C || (cmd & MPSSE_BITMODE))
|
|
xfer_size = 1;
|
|
else
|
|
xfer_size = mpsse->xsize;
|
|
|
|
num_blocks = (size / xfer_size);
|
|
if (size % xfer_size)
|
|
num_blocks++;
|
|
|
|
/*
|
|
* The total size of the data will be the data size + the write
|
|
* command
|
|
*/
|
|
total_size = size + (CMD_SIZE * num_blocks);
|
|
|
|
buf = malloc(total_size);
|
|
if (!buf)
|
|
return NULL;
|
|
|
|
memset(buf, 0, total_size);
|
|
|
|
for (j = 0; j < num_blocks; j++) {
|
|
dsize = size - k;
|
|
if (dsize > xfer_size)
|
|
dsize = xfer_size;
|
|
|
|
/* The reported size of this block is block size - 1 */
|
|
rsize = dsize - 1;
|
|
|
|
/* Copy in the command for this block */
|
|
buf[i++] = cmd;
|
|
buf[i++] = (rsize & 0xFF);
|
|
if (!(cmd & MPSSE_BITMODE))
|
|
buf[i++] = ((rsize >> 8) & 0xFF);
|
|
|
|
/* On a write, copy the data to transmit after the command */
|
|
if (cmd == mpsse->tx || cmd == mpsse->txrx) {
|
|
|
|
memcpy(buf + i, data + k, dsize);
|
|
|
|
/* i == offset into buf */
|
|
i += dsize;
|
|
/* k == offset into data */
|
|
k += dsize;
|
|
}
|
|
}
|
|
|
|
*buf_size = i;
|
|
|
|
return buf;
|
|
}
|
|
|
|
/* Set the low bit pins high/low */
|
|
int set_bits_low(struct mpsse_context *mpsse, int port)
|
|
{
|
|
char buf[CMD_SIZE] = { 0 };
|
|
|
|
buf[0] = SET_BITS_LOW;
|
|
buf[1] = port;
|
|
buf[2] = mpsse->tris;
|
|
|
|
return raw_write(mpsse, (unsigned char *)&buf, sizeof(buf));
|
|
}
|
|
|
|
/* Set the high bit pins high/low */
|
|
int set_bits_high(struct mpsse_context *mpsse, int port)
|
|
{
|
|
char buf[CMD_SIZE] = { 0 };
|
|
|
|
buf[0] = SET_BITS_HIGH;
|
|
buf[1] = port;
|
|
buf[2] = mpsse->trish;
|
|
|
|
return raw_write(mpsse, (unsigned char *)&buf, sizeof(buf));
|
|
}
|
|
|
|
/* Set the GPIO pins high/low */
|
|
int gpio_write(struct mpsse_context *mpsse, int pin, int direction)
|
|
{
|
|
int retval = MPSSE_FAIL;
|
|
|
|
/*
|
|
* The first four pins can't be changed unless we are in a stopped
|
|
* status
|
|
*/
|
|
if (pin < NUM_GPIOL_PINS && mpsse->status == STOPPED) {
|
|
/* Convert pin number (0-3) to the corresponding pin bit */
|
|
pin = (GPIO0 << pin);
|
|
|
|
if (direction == HIGH) {
|
|
mpsse->pstart |= pin;
|
|
mpsse->pidle |= pin;
|
|
mpsse->pstop |= pin;
|
|
} else {
|
|
mpsse->pstart &= ~pin;
|
|
mpsse->pidle &= ~pin;
|
|
mpsse->pstop &= ~pin;
|
|
}
|
|
|
|
retval = set_bits_low(mpsse, mpsse->pstop);
|
|
} else if (pin >= NUM_GPIOL_PINS && pin < NUM_GPIO_PINS) {
|
|
/* Convert pin number (4 - 11) to the corresponding pin bit */
|
|
pin -= NUM_GPIOL_PINS;
|
|
|
|
if (direction == HIGH)
|
|
mpsse->gpioh |= (1 << pin);
|
|
else
|
|
mpsse->gpioh &= ~(1 << pin);
|
|
|
|
retval = set_bits_high(mpsse, mpsse->gpioh);
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
/* Checks if a given MPSSE context is valid. */
|
|
int is_valid_context(struct mpsse_context *mpsse)
|
|
{
|
|
int retval = 0;
|
|
|
|
if (mpsse != NULL && mpsse->open)
|
|
retval = 1;
|
|
|
|
return retval;
|
|
}
|