Initial commit of MAXQ10xx example client.

pull/345/head
Anthony Hu 2022-11-08 14:22:48 +00:00
parent c3491327ed
commit 6e05363804
5 changed files with 587 additions and 0 deletions

36
maxq10xx/Makefile 100644
View File

@ -0,0 +1,36 @@
# MAXQ10xx Examples Makefile
CC = gcc
LIB_PATH = /usr/local
CFLAGS = -Wall -I$(LIB_PATH)/include
LIBS = -L$(LIB_PATH)/lib -lm
# option variables
DYN_LIB = -lwolfssl
STATIC_LIB = $(LIB_PATH)/lib/libwolfssl.a
DEBUG_FLAGS = -g -DDEBUG
DEBUG_INC_PATHS = -MD
OPTIMIZE = -Os
# Options
#CFLAGS+=$(DEBUG_FLAGS)
CFLAGS+=$(OPTIMIZE)
#LIBS+=$(STATIC_LIB)
LIBS+=$(DYN_LIB)
# build targets
SRC=$(wildcard *.c)
TARGETS=$(patsubst %.c, %, $(SRC))
.PHONY: clean all
all: $(TARGETS)
debug: CFLAGS+=$(DEBUG_FLAGS)
debug: all
# build template
%: %.c
$(CC) -o $@ $< $(CFLAGS) $(LIBS)
clean:
rm -f $(TARGETS)

149
maxq10xx/README.md 100644
View File

@ -0,0 +1,149 @@
# wolfSSL with Analog Devices MAXQ10xx
This example implements a very simple client application that uses the Analog
Devices MAXQ1065 or MAXQ1080 to do cryptographic operations. Please see the
product documentation for what operations are supported.
NOTE: These instructions are for a MAXQ1065 or MAXQ1080 evaluation board plugged
into the 40-pin GPIO headers of a RaspberryPi. The SDK and example
application are built and executed on the RaspberryPi.
## Building and Installing wolfSSL
You need to have wolfSSL built via the MAXQ10xx SDK. Please contact Analog
Devices to request the SDK. Make sure you have all the required hardware and
software. Follow the instructions to build the SDK. Once completed, there will
be two instances of wolfSSL in the SDK directory; one for server operations
(`wolfssl`) and one for client operations (`maxq10xx-wolfssl`). The client
instance's cryptographic operations are performed by the MAXQ1065 or MAXQ1080.
Enter the `maxq10xx-wolfssl` and install the client instance:
```
cd /path/to/maxq10xx-sdk/maxq10xx-wolfssl
sudo make install
sudo ldconfig
```
This will put the appropriate header files and dynamic libraries in
`/usr/local/include` and `/usr/local/lib/`.
NOTE: Do NOT install the instance for server operations (`wolfssl`).
## Setting Up the MAXQ1065 or MAXQ1080
Follow the SDK instructions for generating and loading the desired cryptographic
artifacts into MAXQ1065 or MAXQ1080. This will depend on the TLS version and
algorithms you want to use.
## Dummy Keys
The build of wolfSSL uses our pkcallbacks configuration to allow MAXQ1065 or
MAXQ1080 to do the cryptographic operations. In order for wolfSSL to understand
the algorithms being used, on the command line we substitute the private key
with a dummy public key at runtime. You can generate these dummy public keys by
running the following commands:
```
openssl x509 -in <ecc_cert>.pem -pubkey -noout > ecc-p256-pub.pem
openssl x509 -in <rsa_cert>.pem -pubkey -noout > rsa-2048-pub.pem
```
`<ecc_cert>.pem` must be a certificate with an ECC P-256 public key in it.
`<rsa_cert>.pem` must be a certificate with an RSA 2048-bit public key in it.
For your convenience, they have already been provided.
```
make maxq10xx-wolfssl-client
```
## Running the Example
The client and server are executed with different command-line parameters
depending on the desired algorithms and TLS version. First, go into the correct
locations in your shell:
```
cd /path/to/maxq10xx-sdk/wolfssl
```
```
cd /path/to/wolfssl-examples/maxq10xx
```
Depending on which of the following algorithms and TLS versions, execute the
associated commands as shown.
### TLS 1.2 PSK (MAXQ1065 or MAXQ1080)
```
./examples/server/server -s -v 3 -l PSK-AES128-CCM-8
```
```
./maxq10xx-wolfssl-client -tls12 -psk
```
### TLS 1.2 ECC (MAXQ1065 or MAXQ1080)
```
./examples/server/server -F -v 3 -l ECDHE-ECDSA-AES128-GCM-SHA256 \
-c ../pki/CA_secp256r1/cert_server_ECDSA_secp256r1_secp256r1.pem \
-k ../pki/CA_secp256r1/privkey_server_ECDSA_secp256r1_secp256r1.pem \
-A ../pki/CA_secp256r1/cert_CA.pem
```
```
./maxq10xx-wolfssl-client -tls12 -ecc
```
### TLS 1.3 PSK (Only MAXQ1080)
```
./examples/server/server -v 4 -s -l TLS13-AES128-GCM-SHA256
```
```
./maxq10xx-wolfssl-client -tls13 -psk
```
### TLS 1.3 ECC (Only MAXQ1080)
```
./examples/server/server -F -v 4 -l TLS13-AES128-GCM-SHA256 \
-c ../pki/CA_secp256r1/cert_server_ECDSA_secp256r1_secp256r1.pem \
-k ../pki/CA_secp256r1/privkey_server_ECDSA_secp256r1_secp256r1.pem \
-A ../pki/CA_secp256r1/cert_CA.pem
```
```
./maxq10xx-wolfssl-client -tls13 -ecc
```
### TLS 1.3 RSA and FFDHE (Only MAXQ1080)
```
./examples/server/server -F -v 4 -l TLS13-AES128-GCM-SHA256 \
-c ../pki/CA_RSA_2048/cert_server_RSA_2048_RSA_2048.pem \
-k ../pki/CA_RSA_2048/privkey_server_RSA_2048_RSA_2048.pem \
-A ../pki/CA_RSA_2048/cert_CA.pem
```
```
./maxq10xx-wolfssl-client -tls13 -rsa
```
### Expected Output
The server will print very little status information about the algorithms and
ciphersuite negotiated. It will wait for a message from the client.
The client will give lots of debug and status logging. It will then prompt the
user for a message. You should type in something like "Hello, this is MAXQ!" and
press enter.
The server will print out the message you typed, send the message "I hear you
fa shizzle!" and then terminate.
The client will print the message it received from the server along with more
debug and status logging and then terminate.

View File

@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEedj066yAnDwNDvUCfb0qgTutLVI3
WdOLH7S4Rs+f3fmipHapKnu3BhCGW3L5CHeoCOedCgSigIsCNJdwS8z2jA==
-----END PUBLIC KEY-----

View File

@ -0,0 +1,389 @@
/* maxq10xx-wolfssl-client.c
*
* Based on client-tls-pkcallback.c
*
* Copyright (C) 2006-2022 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* This example shows how to write a simple TLS client that uses the features
* of the Analog Devices MAXQ 1065 and 1080. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
/* wolfSSL */
#ifndef WOLFSSL_USER_SETTINGS
#include <wolfssl/options.h>
#endif
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/sha256.h>
#include <wolfssl/wolfcrypt/cryptocb.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#if (defined(WOLFSSL_MAXQ1065) || defined(WOLFSSL_MAXQ108X)) && \
defined(HAVE_PK_CALLBACKS) && defined(WOLF_CRYPTO_CB) && \
!defined(NO_PSK) && !defined(HAVE_EXTENDED_MASTER) && \
defined(NO_WOLFSSL_SERVER)
/* -------------- */
/* Configurations */
/* -------------- */
/* Please define this if you want wolfSSL's debug output */
#define WANT_DEBUG
/* Please set the server's address and the port it listens on */
#define DEFAULT_SERVER "127.0.0.1"
#define DEFAULT_PORT 11111
/* ------------------------------------ */
/* No modifications required below here */
/* ------------------------------------ */
/* identity is OpenSSL testing default for openssl s_client, keep same */
static const char* kIdentityStr = "Client_identity";
static WC_INLINE unsigned int my_psk_client_cb(WOLFSSL* ssl, const char* hint,
char* identity, unsigned int id_max_len, unsigned char* key,
unsigned int key_max_len)
{
(void)ssl;
(void)hint;
(void)key;
(void)key_max_len;
/* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
XSTRNCPY(identity, kIdentityStr, id_max_len);
/* For TLS 1.2, we indicate that MAXQ has the PSK. */
return USE_HW_PSK;
}
#ifdef WOLFSSL_TLS13
static WC_INLINE unsigned int my_psk_client_cs_cb(WOLFSSL* ssl,
const char* hint, char* identity, unsigned int id_max_len,
unsigned char* key, unsigned int key_max_len, const char* ciphersuite)
{
(void)ssl;
(void)hint;
(void)key;
(void)key_max_len;
#ifdef WOLFSSL_PSK_MULTI_ID_PER_CS
/* Multiple calls for each cipher suite. First identity byte indicates the
* number of identites seen so far for cipher suite. */
if (identity[0] != 0) {
return 0;
}
#endif
/* see internal.h MAX_PSK_ID_LEN for PSK identity limit */
XSTRNCPY(identity, kIdentityStr, id_max_len);
XSTRNCAT(identity, ciphersuite + XSTRLEN(ciphersuite) - 6, id_max_len);
/* For TLS 1.3, we just return an unmodified key. */
return 32;
}
#endif /* WOLFSSL_TLS13 */
static void print_usage() {
fprintf(stderr, "usage: ./maxq10xx-wolfssl-client [-tls12|-tls13] "
"[-ecc|-rsa|-psk] <cipher suite>\n");
fprintf(stderr, "Use `example/client/client -e` to get a list of cipher "
"suites.\n");
fprintf(stderr, "Specifying a cipher suite is Optional.\n");
}
#define TLS12 1
#define TLS13 2
#define ECC 1
#define RSA 2
#define PSK 3
static int tls_version = TLS12;
static int alg = ECC;
static char *key_file = NULL;
static char *ciphersuite = NULL;
static int cmd_line_parse(int argc, char** argv) {
const size_t tls_vers_len = 6;
const size_t alg_len = 4;
if ((argc != 3) && (argc != 4)) {
print_usage();
return -1;
}
if (strncmp("-tls12", argv[1], tls_vers_len) == 0) {
tls_version = TLS12;
}
else if (strncmp("-tls13", argv[1], tls_vers_len) == 0) {
#ifdef WOLFSSL_TLS13
tls_version = TLS13;
#else
fprintf(stderr, "TLS 1.3 is not supported on MAXQ1065.\n");
return -1;
#endif
}
else {
print_usage();
return -1;
}
if (strncmp("-ecc", argv[2], alg_len) == 0) {
alg = ECC;
key_file = "ecc-p256-pub.pem";
}
else if (strncmp("-rsa", argv[2], alg_len) == 0) {
alg = RSA;
key_file = "rsa-2048-pub.pem";
}
else if (strncmp("-psk", argv[2], alg_len) == 0) {
alg = PSK;
}
else {
print_usage();
return -1;
}
if (argc == 4) {
ciphersuite = argv[3];
}
return 0;
}
int main(int argc, char** argv)
{
int ret, err;
int sockfd = SOCKET_INVALID;
struct sockaddr_in servAddr;
char buff[256];
size_t len;
/* declare wolfSSL objects */
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
/* Command-line parameter check */
ret = cmd_line_parse(argc, argv);
if (ret < 0) {
goto exit;
}
/* Create a socket that uses an internet IPv4 address.
* Sets the socket to be stream based (TCP).
* 0 means choose the default protocol. */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "ERROR: failed to create the socket\n");
ret = -1;
goto exit;
}
/* Initialize the server address struct with zeros */
memset(&servAddr, 0, sizeof(servAddr));
/* Fill in the server address */
servAddr.sin_family = AF_INET; /* using IPv4 */
servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
/* Get the server IPv4 address from the command line call */
if (inet_pton(AF_INET, DEFAULT_SERVER, &servAddr.sin_addr) != 1) {
fprintf(stderr, "ERROR: invalid address\n");
ret = -1;
goto exit;
}
/* Connect to the server */
if ((ret = connect(sockfd, (struct sockaddr*) &servAddr, sizeof(servAddr)))
== -1) {
fprintf(stderr, "ERROR: failed to connect\n");
goto exit;
}
/*---------------------------------------------------*/
/* Start of wolfSSL initialization and configuration */
/*---------------------------------------------------*/
#ifdef WANT_DEBUG
wolfSSL_Debugging_ON();
#endif
/* Initialize wolfSSL */
if ((ret = wolfSSL_Init()) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to initialize the library\n");
goto exit;
}
/* Create and initialize WOLFSSL_CTX */
#ifdef WOLFSSL_TLS13
if (tls_version == TLS13)
ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
else
#endif /* WOLFSSL_TLS13 */
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
if (ctx == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
ret = -1;
goto exit;
}
/* At this point you would normally register a CA certificate, however, it
* resides in MAXQ10xx and has already been registered. */
/* Load the dummy private key; actually a public key. The actual private
* key resides in MAXQ 10xx. */
if (key_file != NULL) {
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, key_file,
WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the "
"file.\n", key_file);
goto exit;
}
}
/* If specified, set the ciphersuite. */
if (ciphersuite != NULL) {
if (wolfSSL_CTX_set_cipher_list(ctx, ciphersuite) != WOLFSSL_SUCCESS) {
fprintf(stderr, "Invalid cipher suite.\n");
print_usage();
goto exit;
}
}
if (alg == PSK) {
wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb);
#ifdef WOLFSSL_TLS13
if (tls_version == TLS13) {
wolfSSL_CTX_set_psk_client_cs_callback(ctx, my_psk_client_cs_cb);
}
#endif /* WOLFSSL_TLS13 */
if (ciphersuite != NULL) {
wolfSSL_CTX_set_psk_callback_ctx(ctx, (void*)ciphersuite);
}
}
/* Validate peer certificate */
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
/* Create a WOLFSSL object */
if ((ssl = wolfSSL_new(ctx)) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
ret = -1;
goto exit;
}
#ifdef WOLFSSL_TLS13
if (alg == RSA) {
if (wolfSSL_UseKeyShare(ssl, WOLFSSL_FFDHE_2048) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
ret = -1;
goto exit;
}
}
#endif /* WOLFSSL_TLS13 */
/* Attach wolfSSL to the socket */
if ((ret = wolfSSL_set_fd(ssl, sockfd)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to set the file descriptor\n");
goto exit;
}
/* Connect to wolfSSL on the server side */
do {
ret = wolfSSL_connect(ssl);
err = wolfSSL_get_error(ssl, ret);
} while (err == WC_PENDING_E);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to connect to wolfSSL\n");
goto exit;
}
/* Get a message for the server from stdin */
printf("Message for server: ");
memset(buff, 0, sizeof(buff));
if (fgets(buff, sizeof(buff), stdin) == NULL) {
fprintf(stderr, "ERROR: failed to get message for server\n");
ret = -1;
goto exit;
}
len = strnlen(buff, sizeof(buff));
/* Send the message to the server */
if ((ret = wolfSSL_write(ssl, buff, len)) != len) {
fprintf(stderr, "ERROR: failed to write entire message\n");
fprintf(stderr, "%d bytes of %d bytes were sent", ret, (int) len);
goto exit;
}
/* Read the server data into our buff array */
memset(buff, 0, sizeof(buff));
if ((ret = wolfSSL_read(ssl, buff, sizeof(buff)-1)) == -1) {
fprintf(stderr, "ERROR: failed to read\n");
goto exit;
}
/* Print to stdout any data the server sends */
printf("Server: %s\n", buff);
ret = 0; /* success */
exit:
/* Cleanup and return */
if (sockfd != SOCKET_INVALID)
close(sockfd);
if (ssl != NULL)
wolfSSL_free(ssl);
if (ctx != NULL)
wolfSSL_CTX_free(ctx);
wolfSSL_Cleanup();
return ret;
}
#else
int main(int argc, char** argv)
{
printf("Warning: Required flags have not been used!\n"
"Please configure with the following flags:\n"
" --enable-pkcallbacks\n"
" --enable-cryptocb\n"
" --disable-extended-master\n"
" --enable-psk\n"
" --enable-aesccm\n"
" --with-maxq10xx=MAXQ108x|MAXQ1065\n"
" CFLAGS=-DNO_WOLFSSL_SERVER\n"
);
return -1;
}
#endif /* (WOLFSSL_MAXQ1065 || WOLFSSL_MAXQ108X) && HAVE_PK_CALLBACKS &&
* WOLF_CRYPTO_CB && !NO_PSK && !HAVE_EXTENDED_MASTER &&
* NO_WOLFSSL_SERVER */

View File

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp0Z1C9aj1MSYFw+TQPBG
NaYDYaic3Y1LyvziYtMMas/C5Kok4m9AWo/87Bl19CVd1VCG4syl2+GtfEkA6WW7
/dTLVZn+XtGb+dvbILRxcTWUUa/87OZGfwAhrULFwcguKN51PgncZ54Rkej9qAHe
SeikJh0K8wgGousYNgNCfljnDoMKazKYCyiGYuwmvdx37596z8Ii99W+OTg38cft
lTEMSmBy8MEswme6KgA62+cVZDYlngm1ox8VwNMMntDx2nXsw0nXwlOd9Rd+Tv9D
T9raIyGxIyxaOjsUsSyRipKUuJUgFY40jO+VuHIpvNxqlG4ISaib8zdB96ML+WFB
8QIDAQAB
-----END PUBLIC KEY-----