diff --git a/.gitignore b/.gitignore index 8fdd2ac1..7e2546ce 100644 --- a/.gitignore +++ b/.gitignore @@ -145,3 +145,6 @@ pkcs11/server-tls-pkcs11 pkcs11/softhsm2.conf pkcs11/softhsm2 +crypto/rsa-pss/rsa-pss +crypto/rsa-pss/rsa-public.key +crypto/rsa-pss/sign.txt diff --git a/crypto/rsa-pss/Makefile b/crypto/rsa-pss/Makefile new file mode 100644 index 00000000..ba11dae2 --- /dev/null +++ b/crypto/rsa-pss/Makefile @@ -0,0 +1,11 @@ +CC=gcc +CFLAGS=-Wall +LIBS= -lwolfssl + +rsa-pss: rsa-pss.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +.PHONY: clean + +clean: + rm -f *.o rsa-pss diff --git a/crypto/rsa-pss/README.md b/crypto/rsa-pss/README.md new file mode 100644 index 00000000..39bdebf1 --- /dev/null +++ b/crypto/rsa-pss/README.md @@ -0,0 +1,23 @@ +# RSA PSS Example + +## Building + +### Build wolfSSL + +``` +./configure --enable-rsapss --enable-keygen --enable-certgen --enable-certext +make +sudo make install +``` + +### Build rsa-pss +`make` + + +## Usage + +Creates a key-pair, exports public key to rsa-public.key and signs message in variable `szMessage`. +`./rsa-pss -o sign.txt` + +Uses public key at `rsa-public.key` to verify signed data. +`./rsa-pss -v sign.txt` diff --git a/crypto/rsa-pss/rsa-pss.c b/crypto/rsa-pss/rsa-pss.c new file mode 100644 index 00000000..e0dcc10e --- /dev/null +++ b/crypto/rsa-pss/rsa-pss.c @@ -0,0 +1,152 @@ +/* rsa-pss.c + * + * Copyright (C) 2006-2018 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-1335, USA + */ + +/* +* An implementation of RSA PSS digital signature using wolfSSL +*/ + +#include +#include + +#include +#include +#include +#include + +static const char* kRsaPubKey = "./rsa-public.key"; +#define MAX_DER_SIZE 2048 +#define RSA_KEY_SIZE 2048 + +int main(int argc, char** argv) +{ + RsaKey* pRsaKey = NULL; + WC_RNG rng; + const char* szMessage = "This is the string to be signed"; + unsigned char pSignature[RSA_KEY_SIZE/8]; + unsigned char pDecrypted[RSA_KEY_SIZE/8]; + int status = 0; + int sz; + word32 idx = 0; + unsigned char derBuf[MAX_DER_SIZE]; + + pRsaKey = malloc(sizeof(RsaKey)); + wolfSSL_Debugging_ON(); + + wolfSSL_Init(); + + wc_InitRsaKey(pRsaKey, NULL); + wc_InitRng(&rng); + wc_RsaSetRNG(pRsaKey, &rng); + + if (memcmp(argv[1], "-o", 2) == 0) { + printf("generating RSA key to make a PSS signature\n"); + /* Generate an RSA key pair */ + if (wc_MakeRsaKey(pRsaKey, RSA_KEY_SIZE, 0x010001, &rng) != 0) { + printf("failed to create rsa key\n"); + } + + if (pRsaKey) + { + FILE* f; + f = fopen(kRsaPubKey, "wb"); + printf("writing public key to %s\n", kRsaPubKey); + if (f == NULL) { + printf("unable to write out private key\n"); + } + else { + sz = wc_RsaKeyToDer(pRsaKey, derBuf, sizeof(derBuf)); + if (sz <= 0) { + printf("error with rsa load der %d\n", sz); + } + fwrite(derBuf, 1, sz, f); + fclose(f); + } + } + } + else { + printf("reading in RSA key to verify signature\n"); + sz = wolfSSL_PemPubKeyToDer(kRsaPubKey, derBuf, sizeof(derBuf)); + wc_RsaPublicKeyDecode(derBuf, &idx, pRsaKey, sz); + } + if (!pRsaKey) + { + printf("RSA_generate_key failed with error\n"); + goto prog_end; + } + + if (memcmp(argv[1], "-o", 2) == 0) { + FILE* f = fopen(argv[2], "wb"); + printf("Creating PSS signature and writing to %s\n", argv[2]); + if (f == NULL) { + printf("error opening output file %s\n", argv[2]); + goto prog_end; + } + + /* perform digital signature */ + status = wc_RsaPSS_Sign((byte*)szMessage, sizeof(szMessage), + pSignature, sizeof(pSignature), + WC_HASH_TYPE_SHA256, WC_MGF1SHA256, pRsaKey, &rng); + if (status <= 0) + { + printf("RSA_private_encrypt failed with error %d\n", status); + goto prog_end; + } + + fwrite(pSignature, 1, status, f); + fclose(f); + } + else { + FILE* f; + f = fopen(argv[2], "rb"); + if (f == NULL) { + printf("unable to open %s\n", argv[2]); + goto prog_end; + } + fread(pSignature, 1, sizeof(pSignature), f); + fclose(f); + + /* now we will verify the signature + Start by a RAW decrypt of the signature + */ + byte* pt = pDecrypted; + status = wc_RsaPSS_VerifyInline(pSignature, sizeof(pSignature), &pt, + WC_HASH_TYPE_SHA256, WC_MGF1SHA256, pRsaKey); + if (status <= 0) + { + printf("RSA_public_decrypt failed with error %d\n", status); + goto prog_end; + } + else + { + printf("RSA PSS verify success\n"); + } + } + +prog_end: + + if (pRsaKey) + free(pRsaKey); + + wolfSSL_Cleanup(); + + return 0; +} +