Skip to content

Commit

Permalink
Merge pull request #153 from kojo1/dilithium
Browse files Browse the repository at this point in the history
Dilithium: fix minor errors
  • Loading branch information
JacobBarthelmeh authored Nov 1, 2024
2 parents 33a2785 + 327a339 commit 59b0884
Show file tree
Hide file tree
Showing 11 changed files with 795 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/clu_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ static const struct option mode_options[] = {
{"rsa", no_argument, 0, WOLFCLU_RSA },
{"ecc", no_argument, 0, WOLFCLU_ECC },
{"ed25519", no_argument, 0, WOLFCLU_ED25519 },
{"dilithium", no_argument, 0, WOLFCLU_DILITHIUM },
{"dgst", no_argument, 0, WOLFCLU_DGST },
{"verify", no_argument, 0, WOLFCLU_VERIFY },
{"pkcs7", no_argument, 0, WOLFCLU_PKCS7 },
Expand Down Expand Up @@ -276,6 +277,7 @@ int main(int argc, char** argv)
case WOLFCLU_RSALEGACY:
case WOLFCLU_ECC:
case WOLFCLU_ED25519:
case WOLFCLU_DILITHIUM:
ret = wolfCLU_sign_verify_setup(argc, argv);
break;

Expand Down
237 changes: 237 additions & 0 deletions src/genkey/clu_genkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,243 @@ int wolfCLU_genKey_RSA(WC_RNG* rng, char* fName, int directive, int fmt, int
#endif
}


int wolfCLU_genKey_Dilithium(WC_RNG* rng, char* fName, int directive, int fmt,
int keySz, int level, int withAlg)
{
#ifdef HAVE_DILITHIUM
int ret = WOLFCLU_SUCCESS;

XFILE file = NULL;
int fNameSz = 0;
int fExtSz = 6; // size of ".priv\0" or ".pub\0\0"
char fExtPriv[6] = ".priv\0";
char fExtPub[6] = ".pub\0\0";
char* fOutNameBuf = NULL;

#ifdef NO_AES
/* use 16 bytes for AES block size */
size_t maxDerBufSz = 4 * keySz * 16;
#else
size_t maxDerBufSz = 4 * keySz * AES_BLOCK_SIZE;
#endif /* NO_AES */

byte* derBuf = NULL;
byte* pemBuf = NULL;
byte* outBuf = NULL;
int derBufSz = -1;
int pemBufSz = 0;
int outBufSz = 0;

#ifdef WOLFSSL_SMALL_STACK
dilithium_key* key;
key = (dilithium_key*)XMALLOC(sizeof(dilithium_key), key.HEAP_HINT,
DYNAMIC_TYPE_DILITHIUM);
if (key == NULL) {
return MEMORY_E;
}
#else
dilithium_key key[1];
#endif

if (rng == NULL || fName == NULL) {
return BAD_FUNC_ARG;
}

/* init the dilithium key */
if (wc_dilithium_init(key) != 0) {
wolfCLU_LogError("Failed to initialize Dilithium Key.\nRET: %d", ret);
#ifdef WOLFSSL_SMALL_STACK
wc_dilithium_free(key);
#endif
return ret;
}
XMEMSET(key, 0, sizeof(dilithium_key));

/* set the level of the dilithium key */
if (wc_dilithium_set_level(key, level) != 0) {
#ifdef WOLFSSL_SMALL_STACK
wc_dilithium_free(key);
#endif
return WOLFCLU_FAILURE;
}

/* make the dilithium key */
if (wc_dilithium_make_key(key, rng) != 0) {
#ifdef WOLFSSL_SMALL_STACK
wc_dilithium_free(key);
#endif
return WOLFCLU_FAILURE;
}

/* set up the file name output buffer */
if (ret == WOLFCLU_SUCCESS) {
fNameSz = (int)XSTRLEN(fName);
fOutNameBuf = (char*)XMALLOC(fNameSz + fExtSz + 1, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
if (fOutNameBuf == NULL)
ret = MEMORY_E;
}

if (ret == WOLFCLU_SUCCESS) {
XMEMSET(fOutNameBuf, 0, fNameSz + fExtSz);
XMEMCPY(fOutNameBuf, fName, fNameSz);

derBuf = (byte*)XMALLOC(maxDerBufSz, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) {
ret = MEMORY_E;
}
}

if (ret == WOLFCLU_SUCCESS) {
switch (directive) {
case PRIV_AND_PUB_FILES:
/* Fall through to PRIV_ONLY_FILE */
FALL_THROUGH;
case PRIV_ONLY_FILE:
/* add on the final part of the file name ".priv" */
XMEMCPY(fOutNameBuf + fNameSz, fExtPriv, fExtSz);
WOLFCLU_LOG(WOLFCLU_L0, "Private key file = %s", fOutNameBuf);

/* Private key to der */
derBufSz = wc_Dilithium_PrivateKeyToDer(key,
derBuf, (word32)maxDerBufSz);
if (derBufSz < 0) {
ret = derBufSz;
}
outBuf = derBuf;
outBufSz = derBufSz;

/* check if should convert to PEM format */
if (ret == WOLFCLU_SUCCESS && fmt == PEM_FORM) {
pemBufSz = wolfCLU_KeyDerToPem(derBuf, derBufSz, &pemBuf,
PRIVATEKEY_TYPE, DYNAMIC_TYPE_TMP_BUFFER);
if (pemBufSz <= 0 || pemBuf == NULL) {
ret = WOLFCLU_FAILURE;
}
outBuf = pemBuf;
outBufSz = pemBufSz;
}

/* open file and write Private key */
if (ret == WOLFCLU_SUCCESS) {
file = XFOPEN(fOutNameBuf, "wb");
if (file == XBADFILE) {
wolfCLU_LogError("unable to open file %s",
fOutNameBuf);
ret = OUTPUT_FILE_ERROR;
}
}

if (ret == WOLFCLU_SUCCESS) {
if ((int)XFWRITE(outBuf, 1, outBufSz, file) <= 0) {
ret = OUTPUT_FILE_ERROR;
}
}

if (directive != PRIV_AND_PUB_FILES) {
break;
}

XFCLOSE(file);
file = NULL;
XFREE(derBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
derBuf = NULL;
XFREE(pemBuf, HEAP_HINT, DYNAMIC_TYPE_PRIVATE_KEY);
pemBuf = NULL;

FALL_THROUGH;
case PUB_ONLY_FILE:
/* add on the final part of the file name ".priv" */
XMEMCPY(fOutNameBuf + fNameSz, fExtPub, fExtSz);
WOLFCLU_LOG(WOLFCLU_L0, "Public key file = %s", fOutNameBuf);

derBuf = (byte*)XMALLOC(maxDerBufSz, HEAP_HINT,
DYNAMIC_TYPE_TMP_BUFFER);
if (derBuf == NULL) {
ret = MEMORY_E;
}

derBufSz = wc_Dilithium_PublicKeyToDer(key, derBuf,
(word32)maxDerBufSz, withAlg);
if (derBufSz < 0) {
ret = derBufSz;
}
else {
outBuf = derBuf;
outBufSz = derBufSz;
}

/* check if should convert to PEM format */
if (ret == WOLFCLU_SUCCESS && fmt == PEM_FORM) {
pemBufSz = wolfCLU_KeyDerToPem(derBuf, derBufSz, &pemBuf,
PUBLICKEY_TYPE, DYNAMIC_TYPE_TMP_BUFFER);
if (pemBufSz <= 0 || pemBuf == NULL) {
ret = WOLFCLU_FAILURE;
}
outBuf = pemBuf;
outBufSz = pemBufSz;
}

/* open file and write Public key */
if (ret == WOLFCLU_SUCCESS) {
file = XFOPEN(fOutNameBuf, "wb");
if (file == XBADFILE) {
wolfCLU_LogError("unable to open file %s",
fOutNameBuf);
ret = OUTPUT_FILE_ERROR;
}
}

if (ret == WOLFCLU_SUCCESS) {
if ((int)XFWRITE(outBuf, 1, outBufSz, file) <= 0) {
ret = OUTPUT_FILE_ERROR;
}
}

break;
default:
wolfCLU_LogError("Invalid directive");
ret = BAD_FUNC_ARG;
}
}

if (file != NULL)
XFCLOSE(file);

if (derBuf != NULL) {
wolfCLU_ForceZero(derBuf, (unsigned int)maxDerBufSz);
XFREE(derBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}

if (pemBuf != NULL) {
wolfCLU_ForceZero(pemBuf, pemBufSz);
XFREE(pemBuf, HEAP_HINT, DYNAMIC_TYPE_PRIVATE_KEY);
}

if (fOutNameBuf != NULL) {
XFREE(fOutNameBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
}

#ifdef WOLFSSL_SMALL_STACK
wc_dilithium_free(key);
#endif

return ret;
#else
(void)rng;
(void)fName;
(void)directive;
(void)fmt;
(void)keySz;
(void)level;
(void)withAlg;

return NOT_COMPILED_IN;
#endif /* HAVE_DILITHIUM */
}

#endif /* WOLFSSL_KEY_GEN && !NO_ASN*/


Expand Down
67 changes: 67 additions & 0 deletions src/genkey/clu_genkey_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,73 @@ int wolfCLU_genKeySetup(int argc, char** argv)
return NOT_COMPILED_IN;
#endif /* NO_RSA */
}
else if (XSTRNCMP(keyType, "dilithium", 9) == 0) {
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_KEY_GEN)
int directiveArg = PRIV_AND_PUB_FILES;
int keySz = DILITHIUM_LEVEL2_PRV_KEY_SIZE;
int level = 2;
int withAlg = DILITHIUM_LEVEL2k;

WOLFCLU_LOG(WOLFCLU_L0, "Generate Dilithium Key");

/* get the level argument */
ret = wolfCLU_checkForArg("-level", 6, argc, argv);
if (ret > 0) {
level = XATOI(argv[ret+1]);
switch (level) {
case 2:
keySz = DILITHIUM_LEVEL2_PRV_KEY_SIZE;
withAlg = DILITHIUM_LEVEL2k;
break;
case 3:
keySz = DILITHIUM_LEVEL3_PRV_KEY_SIZE;
withAlg = DILITHIUM_LEVEL3k;
break;
case 5:
keySz = DILITHIUM_LEVEL5_PRV_KEY_SIZE;
withAlg = DILITHIUM_LEVEL5k;
break;
default:
WOLFCLU_LOG(WOLFCLU_L0, "Invalid -level (%s), using level%d",
argv[ret+1], level);
break;
}
}
else {
/* no option -level */
WOLFCLU_LOG(WOLFCLU_L0, "No -level [ 2 | 3 | 5 ]");
WOLFCLU_LOG(WOLFCLU_L0, "DEFAULT: use Level %d", level);
}

/* get the directive argument */
ret = wolfCLU_checkForArg("-output", 7, argc, argv);
if (ret > 0) {
if (argv[ret+1] != NULL) {
if (XSTRNCMP(argv[ret+1], "pub", 3) == 0)
directiveArg = PUB_ONLY_FILE;
else if (XSTRNCMP(argv[ret+1], "priv", 4) == 0)
directiveArg = PRIV_ONLY_FILE;
else if (XSTRNCMP(argv[ret+1], "keypair", 7) == 0)
directiveArg = PRIV_AND_PUB_FILES;
}
}
else {
WOLFCLU_LOG(WOLFCLU_L0, "No -output <PUB/PRIV/KEYPAIR>");
WOLFCLU_LOG(WOLFCLU_L0, "DEFAULT: output public and private key pair");
}

WOLFCLU_LOG(WOLFCLU_L0, "using Dilithium%d", level);
ret = wolfCLU_genKey_Dilithium(&rng, keyOutFName, directiveArg, formatArg,
keySz, level, withAlg);

#else
wolfCLU_LogError("Invalid option, Dithium not enabled.");
WOLFCLU_LOG(WOLFCLU_L0, "Please re-configure wolfSSL with --enable-dilithium, "
"--enable-experimental and try again");
wc_FreeRng(&rng);
return NOT_COMPILED_IN;
#endif /* HAVE_DILITHIUM */
}
else {
wolfCLU_LogError("\"%s\" is an invalid key type, or not compiled in", keyType);
wc_FreeRng(&rng);
Expand Down
Loading

0 comments on commit 59b0884

Please sign in to comment.