Static Memory

1. In the echoserver, change the names of the defines for the
   static memory values.
2. Modify the client common functions for keys and certs to take a heap
   value for their allocations.
3. Update the client's use of the common key and cert function calls to
   pass NULL for the heap.
4. Add a static memory description for the sftp client code.
pull/682/head
John Safranek 2024-04-25 14:28:26 -07:00
parent 559f24b476
commit d6d67c889c
5 changed files with 91 additions and 36 deletions

View File

@ -780,7 +780,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
err_sys("If setting priv key, need pub key."); err_sys("If setting priv key, need pub key.");
} }
ret = ClientSetPrivateKey(privKeyName, userEcc); ret = ClientSetPrivateKey(privKeyName, userEcc, NULL);
if (ret != 0) { if (ret != 0) {
err_sys("Error setting private key"); err_sys("Error setting private key");
} }
@ -788,12 +788,12 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
#ifdef WOLFSSH_CERTS #ifdef WOLFSSH_CERTS
/* passed in certificate to use */ /* passed in certificate to use */
if (certName) { if (certName) {
ret = ClientUseCert(certName); ret = ClientUseCert(certName, NULL);
} }
else else
#endif #endif
if (pubKeyName) { if (pubKeyName) {
ret = ClientUsePubKey(pubKeyName, userEcc); ret = ClientUsePubKey(pubKeyName, userEcc, NULL);
} }
if (ret != 0) { if (ret != 0) {
err_sys("Error setting public key"); err_sys("Error setting public key");
@ -1079,7 +1079,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
err_sys("Closing client stream failed"); err_sys("Closing client stream failed");
} }
ClientFreeBuffers(pubKeyName, privKeyName); ClientFreeBuffers(pubKeyName, privKeyName, NULL);
#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) #if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */ wc_ecc_fp_free(); /* free per thread cache */
#endif #endif

View File

@ -241,7 +241,8 @@ static const unsigned int hanselPrivateEccSz = 223;
#if defined(WOLFSSH_CERTS) #if defined(WOLFSSH_CERTS)
static int load_der_file(const char* filename, byte** out, word32* outSz) static int load_der_file(const char* filename, byte** out, word32* outSz,
void* heap)
{ {
WFILE* file; WFILE* file;
byte* in; byte* in;
@ -267,7 +268,7 @@ static int load_der_file(const char* filename, byte** out, word32* outSz)
return -1; return -1;
} }
in = (byte*)WMALLOC(inSz, NULL, 0); in = (byte*)WMALLOC(inSz, heap, 0);
if (in == NULL) { if (in == NULL) {
WFCLOSE(NULL, file); WFCLOSE(NULL, file);
return -1; return -1;
@ -276,7 +277,7 @@ static int load_der_file(const char* filename, byte** out, word32* outSz)
ret = (int)WFREAD(NULL, in, 1, inSz, file); ret = (int)WFREAD(NULL, in, 1, inSz, file);
if (ret <= 0 || (word32)ret != inSz) { if (ret <= 0 || (word32)ret != inSz) {
ret = -1; ret = -1;
WFREE(in, NULL, 0); WFREE(in, heap, 0);
in = 0; in = 0;
inSz = 0; inSz = 0;
} }
@ -652,19 +653,20 @@ int ClientSetEcho(int type)
/* Set certificate to use and public key. /* Set certificate to use and public key.
* returns 0 on success */ * returns 0 on success */
int ClientUseCert(const char* certName) int ClientUseCert(const char* certName, void* heap)
{ {
int ret = 0; int ret = 0;
if (certName != NULL) { if (certName != NULL) {
#ifdef WOLFSSH_CERTS #ifdef WOLFSSH_CERTS
ret = load_der_file(certName, &userPublicKey, &userPublicKeySz); ret = load_der_file(certName, &userPublicKey, &userPublicKeySz, heap);
if (ret == 0) { if (ret == 0) {
userPublicKeyType = publicKeyType; userPublicKeyType = publicKeyType;
userPublicKeyTypeSz = (word32)WSTRLEN((const char*)publicKeyType); userPublicKeyTypeSz = (word32)WSTRLEN((const char*)publicKeyType);
pubKeyLoaded = 1; pubKeyLoaded = 1;
} }
#else #else
(void)heap;
fprintf(stderr, "Certificate support not compiled in"); fprintf(stderr, "Certificate support not compiled in");
ret = WS_NOT_COMPILED; ret = WS_NOT_COMPILED;
#endif #endif
@ -676,7 +678,7 @@ int ClientUseCert(const char* certName)
/* Reads the private key to use from file name privKeyName. /* Reads the private key to use from file name privKeyName.
* returns 0 on success */ * returns 0 on success */
int ClientSetPrivateKey(const char* privKeyName, int userEcc) int ClientSetPrivateKey(const char* privKeyName, int userEcc, void* heap)
{ {
int ret = 0; int ret = 0;
@ -685,14 +687,14 @@ int ClientSetPrivateKey(const char* privKeyName, int userEcc)
#ifndef WOLFSSH_NO_ECC #ifndef WOLFSSH_NO_ECC
ret = wolfSSH_ReadKey_buffer(hanselPrivateEcc, hanselPrivateEccSz, ret = wolfSSH_ReadKey_buffer(hanselPrivateEcc, hanselPrivateEccSz,
WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz, WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz,
&userPrivateKeyType, &userPrivateKeyTypeSz, NULL); &userPrivateKeyType, &userPrivateKeyTypeSz, heap);
#endif #endif
} }
else { else {
#ifndef WOLFSSH_NO_RSA #ifndef WOLFSSH_NO_RSA
ret = wolfSSH_ReadKey_buffer(hanselPrivateRsa, hanselPrivateRsaSz, ret = wolfSSH_ReadKey_buffer(hanselPrivateRsa, hanselPrivateRsaSz,
WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz, WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz,
&userPrivateKeyType, &userPrivateKeyTypeSz, NULL); &userPrivateKeyType, &userPrivateKeyTypeSz, heap);
#endif #endif
} }
isPrivate = 1; isPrivate = 1;
@ -703,7 +705,7 @@ int ClientSetPrivateKey(const char* privKeyName, int userEcc)
ret = wolfSSH_ReadKey_file(privKeyName, ret = wolfSSH_ReadKey_file(privKeyName,
(byte**)&userPrivateKey, &userPrivateKeySz, (byte**)&userPrivateKey, &userPrivateKeySz,
(const byte**)&userPrivateKeyType, &userPrivateKeyTypeSz, (const byte**)&userPrivateKeyType, &userPrivateKeyTypeSz,
&isPrivate, NULL); &isPrivate, heap);
#else #else
printf("file system not compiled in!\n"); printf("file system not compiled in!\n");
ret = NOT_COMPILED_IN; ret = NOT_COMPILED_IN;
@ -716,7 +718,7 @@ int ClientSetPrivateKey(const char* privKeyName, int userEcc)
/* Set public key to use /* Set public key to use
* returns 0 on success */ * returns 0 on success */
int ClientUsePubKey(const char* pubKeyName, int userEcc) int ClientUsePubKey(const char* pubKeyName, int userEcc, void* heap)
{ {
int ret = 0; int ret = 0;
@ -729,7 +731,7 @@ int ClientUsePubKey(const char* pubKeyName, int userEcc)
ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicEcc, ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicEcc,
(word32)strlen(hanselPublicEcc), WOLFSSH_FORMAT_SSH, (word32)strlen(hanselPublicEcc), WOLFSSH_FORMAT_SSH,
&p, &userPublicKeySz, &p, &userPublicKeySz,
&userPublicKeyType, &userPublicKeyTypeSz, NULL); &userPublicKeyType, &userPublicKeyTypeSz, heap);
#endif #endif
} }
else { else {
@ -737,7 +739,7 @@ int ClientUsePubKey(const char* pubKeyName, int userEcc)
ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicRsa, ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicRsa,
(word32)strlen(hanselPublicRsa), WOLFSSH_FORMAT_SSH, (word32)strlen(hanselPublicRsa), WOLFSSH_FORMAT_SSH,
&p, &userPublicKeySz, &p, &userPublicKeySz,
&userPublicKeyType, &userPublicKeyTypeSz, NULL); &userPublicKeyType, &userPublicKeyTypeSz, heap);
#endif #endif
} }
isPrivate = 1; isPrivate = 1;
@ -748,7 +750,7 @@ int ClientUsePubKey(const char* pubKeyName, int userEcc)
ret = wolfSSH_ReadKey_file(pubKeyName, ret = wolfSSH_ReadKey_file(pubKeyName,
&userPublicKey, &userPublicKeySz, &userPublicKey, &userPublicKeySz,
(const byte**)&userPublicKeyType, &userPublicKeyTypeSz, (const byte**)&userPublicKeyType, &userPublicKeyTypeSz,
&isPrivate, NULL); &isPrivate, heap);
#else #else
printf("file system not compiled in!\n"); printf("file system not compiled in!\n");
ret = -1; ret = -1;
@ -771,7 +773,7 @@ int ClientLoadCA(WOLFSSH_CTX* ctx, const char* caCert)
byte* der = NULL; byte* der = NULL;
word32 derSz; word32 derSz;
ret = load_der_file(caCert, &der, &derSz); ret = load_der_file(caCert, &der, &derSz, ctx->heap);
if (ret == 0) { if (ret == 0) {
if (wolfSSH_CTX_AddRootCert_buffer(ctx, der, derSz, if (wolfSSH_CTX_AddRootCert_buffer(ctx, der, derSz,
WOLFSSH_FORMAT_ASN1) != WS_SUCCESS) { WOLFSSH_FORMAT_ASN1) != WS_SUCCESS) {
@ -790,13 +792,14 @@ int ClientLoadCA(WOLFSSH_CTX* ctx, const char* caCert)
} }
void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName) void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName,
void* heap)
{ {
if (pubKeyName != NULL && userPublicKey != NULL) { if (pubKeyName != NULL && userPublicKey != NULL) {
WFREE(userPublicKey, NULL, DYNTYPE_PRIVKEY); WFREE(userPublicKey, heap, DYNTYPE_PRIVKEY);
} }
if (privKeyName != NULL && userPrivateKey != NULL) { if (privKeyName != NULL && userPrivateKey != NULL) {
WFREE(userPrivateKey, NULL, DYNTYPE_PRIVKEY); WFREE(userPrivateKey, heap, DYNTYPE_PRIVKEY);
} }
} }

View File

@ -21,16 +21,17 @@
#ifndef WOLFSSH_COMMON_H #ifndef WOLFSSH_COMMON_H
#define WOLFSSH_COMMON_H #define WOLFSSH_COMMON_H
int ClientLoadCA(WOLFSSH_CTX* ctx, const char* caCert); int ClientLoadCA(WOLFSSH_CTX* ctx, const char* caCert);
int ClientUsePubKey(const char* pubKeyName, int userEcc); int ClientUsePubKey(const char* pubKeyName, int userEcc, void* heap);
int ClientSetPrivateKey(const char* privKeyName, int userEcc); int ClientSetPrivateKey(const char* privKeyName, int userEcc, void* heap);
int ClientUseCert(const char* certName); int ClientUseCert(const char* certName, void* heap);
int ClientSetEcho(int type); int ClientSetEcho(int type);
int ClientUserAuth(byte authType, int ClientUserAuth(byte authType,
WS_UserAuthData* authData, WS_UserAuthData* authData,
void* ctx); void* ctx);
int ClientPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx); int ClientPublicKeyCheck(const byte* pubKey, word32 pubKeySz, void* ctx);
void ClientIPOverride(int flag); void ClientIPOverride(int flag);
void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName); void ClientFreeBuffers(const char* pubKeyName, const char* privKeyName,
void* heap);
#endif /* WOLFSSH_COMMON_H */ #endif /* WOLFSSH_COMMON_H */

View File

@ -623,10 +623,21 @@ static int termios_show(int fd)
* and distList items and summing (32*64 + 128*118 + ...) and adding * and distList items and summing (32*64 + 128*118 + ...) and adding
* the sum of the distList values times the sizeof wc_Memory (rounded up * the sum of the distList values times the sizeof wc_Memory (rounded up
* to a word, 24). This total was 288kb plus change, rounded up to 289. */ * to a word, 24). This total was 288kb plus change, rounded up to 289. */
static const word32 static_sizeList[] = #ifndef ES_STATIC_SIZES
{32,128,384,800,3120,8400,17552,32846,131072}; #define ES_STATIC_SIZES 32,128,384,800,3120,8400,17552,32846,131072
static const word32 static_distList[] = {64,118,3,4,6,2,2,2,1}; #endif
static byte static_buffer[289*1024]; #ifndef ES_STATIC_DISTS
#define ES_STATIC_DISTS 64,118,3,4,6,2,2,2,1
#endif
#ifndef ES_STATIC_LISTSZ
#define ES_STATIC_LISTSZ 9
#endif
#ifndef ES_STATIC_BUFSZ
#define ES_STATIC_BUFSZ (289*1024)
#endif
static const word32 static_sizeList[] = {ES_STATIC_SIZES};
static const word32 static_distList[] = {ES_STATIC_DISTS};
static byte static_buffer[ES_STATIC_BUFSZ];
static void wolfSSH_MemoryPrintStats(ES_HEAP_HINT* hint) static void wolfSSH_MemoryPrintStats(ES_HEAP_HINT* hint)
{ {
@ -2410,7 +2421,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
int ret; int ret;
ret = wc_LoadStaticMemory_ex(&heap, ret = wc_LoadStaticMemory_ex(&heap,
9, static_sizeList, static_distList, ES_STATIC_LISTSZ, static_sizeList, static_distList,
static_buffer, sizeof(static_buffer), static_buffer, sizeof(static_buffer),
WOLFMEM_GENERAL|WOLFMEM_TRACK_STATS, 0); WOLFMEM_GENERAL|WOLFMEM_TRACK_STATS, 0);
if (ret != 0) { if (ret != 0) {

View File

@ -63,6 +63,36 @@ static char* workingDir;
#define AUTOPILOT_PUT 2 #define AUTOPILOT_PUT 2
#ifdef WOLFSSH_STATIC_MEMORY
#include <wolfssl/wolfcrypt/memory.h>
typedef WOLFSSL_HEAP_HINT SFTPC_HEAP_HINT;
/* This static buffer is tuned for building with SFTP only. The static
* buffer size is calulated by multiplying the pairs of sizeList items
* and distList items and summing (32*50 + 128*100 + ...) and adding
* the sum of the distList values times the sizeof wc_Memory (rounded up
* to a word, 24). This total was 268kb plus change, rounded up to 269. */
#ifndef SFTPC_STATIC_SIZES
#define SFTPC_STATIC_SIZES 64,128,384,800,3120,8400,17552,33104,131072
#endif
#ifndef SFTPC_STATIC_DISTS
#define SFTPC_STATIC_DISTS 60,100,4,6,5,2,1,2,1
#endif
#ifndef SFTPC_STATIC_LISTSZ
#define SFTPC_STATIC_LISTSZ 9
#endif
#ifndef SFTPC_STATIC_BUFSZ
#define SFTPC_STATIC_BUFSZ (269*1024)
#endif
static const word32 static_sizeList[] = {SFTPC_STATIC_SIZES};
static const word32 static_distList[] = {SFTPC_STATIC_DISTS};
static byte static_buffer[SFTPC_STATIC_BUFSZ];
#else /* WOLFSSH_STATIC_MEMORY */
typedef void SFTPC_HEAP_HINT;
#endif /* WOLFSSH_STATIC_MEMORY */
static void err_msg(const char* s) static void err_msg(const char* s)
{ {
printf("%s\n", s); printf("%s\n", s);
@ -1143,7 +1173,7 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
char* pubKeyName = NULL; char* pubKeyName = NULL;
char* certName = NULL; char* certName = NULL;
char* caCert = NULL; char* caCert = NULL;
SFTPC_HEAP_HINT* heap = NULL;
int argc = ((func_args*)args)->argc; int argc = ((func_args*)args)->argc;
char** argv = ((func_args*)args)->argv; char** argv = ((func_args*)args)->argv;
@ -1263,7 +1293,17 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
} }
#endif #endif
ret = ClientSetPrivateKey(privKeyName, userEcc); #ifdef WOLFSSH_STATIC_MEMORY
ret = wc_LoadStaticMemory_ex(&heap,
SFTPC_STATIC_LISTSZ, static_sizeList, static_distList,
static_buffer, sizeof(static_buffer),
WOLFMEM_GENERAL, 0);
if (ret != 0) {
err_sys("Couldn't set up static memory pool.\n");
}
#endif /* WOLFSSH_STATIC_MEMORY */
ret = ClientSetPrivateKey(privKeyName, userEcc, heap);
if (ret != 0) { if (ret != 0) {
err_sys("Error setting private key"); err_sys("Error setting private key");
} }
@ -1271,18 +1311,18 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
#ifdef WOLFSSH_CERTS #ifdef WOLFSSH_CERTS
/* passed in certificate to use */ /* passed in certificate to use */
if (certName) { if (certName) {
ret = ClientUseCert(certName); ret = ClientUseCert(certName, heap);
} }
else else
#endif #endif
{ {
ret = ClientUsePubKey(pubKeyName, 0); ret = ClientUsePubKey(pubKeyName, 0, heap);
} }
if (ret != 0) { if (ret != 0) {
err_sys("Error setting public key"); err_sys("Error setting public key");
} }
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL); ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, heap);
if (ctx == NULL) if (ctx == NULL)
err_sys("Couldn't create wolfSSH client context."); err_sys("Couldn't create wolfSSH client context.");
@ -1394,7 +1434,7 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
((func_args*)args)->return_code = ret; ((func_args*)args)->return_code = ret;
} }
ClientFreeBuffers(pubKeyName, privKeyName); ClientFreeBuffers(pubKeyName, privKeyName, heap);
#if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS) #if !defined(WOLFSSH_NO_ECC) && defined(FP_ECC) && defined(HAVE_THREAD_LS)
wc_ecc_fp_free(); /* free per thread cache */ wc_ecc_fp_free(); /* free per thread cache */
#endif #endif