summaryrefslogtreecommitdiffstats
path: root/lib/libssl/src/fips/dsa/fips_dssvs.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libssl/src/fips/dsa/fips_dssvs.c')
-rw-r--r--lib/libssl/src/fips/dsa/fips_dssvs.c306
1 files changed, 306 insertions, 0 deletions
diff --git a/lib/libssl/src/fips/dsa/fips_dssvs.c b/lib/libssl/src/fips/dsa/fips_dssvs.c
new file mode 100644
index 00000000000..50a4d969865
--- /dev/null
+++ b/lib/libssl/src/fips/dsa/fips_dssvs.c
@@ -0,0 +1,306 @@
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include <string.h>
+
+int hex2bin(const char *in, unsigned char *out)
+ {
+ int n1, n2;
+ unsigned char ch;
+
+ for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; )
+ { /* first byte */
+ if ((in[n1] >= '0') && (in[n1] <= '9'))
+ ch = in[n1++] - '0';
+ else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
+ ch = in[n1++] - 'A' + 10;
+ else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
+ ch = in[n1++] - 'a' + 10;
+ else
+ return -1;
+ if(!in[n1])
+ {
+ out[n2++]=ch;
+ break;
+ }
+ out[n2] = ch << 4;
+ /* second byte */
+ if ((in[n1] >= '0') && (in[n1] <= '9'))
+ ch = in[n1++] - '0';
+ else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
+ ch = in[n1++] - 'A' + 10;
+ else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
+ ch = in[n1++] - 'a' + 10;
+ else
+ return -1;
+ out[n2++] |= ch;
+ }
+ return n2;
+ }
+
+BIGNUM *hex2bn(const char *in)
+ {
+ BIGNUM *p=BN_new();
+
+ BN_hex2bn(&p,in);
+
+ return p;
+ }
+
+int bin2hex(const unsigned char *in,int len,char *out)
+ {
+ int n1, n2;
+ unsigned char ch;
+
+ for (n1=0,n2=0 ; n1 < len ; ++n1)
+ {
+ ch=in[n1] >> 4;
+ if (ch <= 0x09)
+ out[n2++]=ch+'0';
+ else
+ out[n2++]=ch-10+'a';
+ ch=in[n1] & 0x0f;
+ if(ch <= 0x09)
+ out[n2++]=ch+'0';
+ else
+ out[n2++]=ch-10+'a';
+ }
+ out[n2]='\0';
+ return n2;
+ }
+
+void pv(const char *tag,const unsigned char *val,int len)
+ {
+ char obuf[2048];
+
+ bin2hex(val,len,obuf);
+ printf("%s = %s\n",tag,obuf);
+ }
+
+void pbn(const char *tag,const BIGNUM *val)
+ {
+ printf("%s = %s\n",tag,BN_bn2hex(val));
+ }
+
+void primes()
+ {
+ char buf[10240];
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ fputs(buf,stdout);
+ if(!strncmp(buf,"Prime= ",7))
+ {
+ BIGNUM *pp;
+
+ pp=BN_new();
+ BN_hex2bn(&pp,buf+7);
+ printf("result= %c\n",
+ BN_is_prime(pp,20,NULL,NULL,NULL) ? 'P' : 'F');
+ }
+ }
+ }
+
+void pqg()
+ {
+ char buf[1024];
+ int nmod=0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if(!strncmp(buf,"[mod = ",7))
+ nmod=atoi(buf+7);
+ else if(!strncmp(buf,"N = ",4))
+ {
+ int n=atoi(buf+4);
+
+ printf("[mod = %d]\n\n",nmod);
+
+ while(n--)
+ {
+ unsigned char seed[20];
+ DSA *dsa;
+ int counter;
+ unsigned long h;
+
+ dsa=DSA_generate_parameters(nmod,seed,0,&counter,&h,NULL,NULL);
+ printf("P = %s\n",BN_bn2hex(dsa->p));
+ printf("Q = %s\n",BN_bn2hex(dsa->q));
+ printf("G = %s\n",BN_bn2hex(dsa->g));
+ pv("Seed",seed,20);
+ printf("c = %d\n",counter);
+ printf("H = %lx\n",h);
+ putc('\n',stdout);
+ }
+ }
+ else
+ fputs(buf,stdout);
+ }
+ }
+
+void keypair()
+ {
+ char buf[1024];
+ int nmod=0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if(!strncmp(buf,"[mod = ",7))
+ nmod=atoi(buf+7);
+ else if(!strncmp(buf,"N = ",4))
+ {
+ DSA *dsa;
+ int n=atoi(buf+4);
+
+ printf("[mod = %d]\n\n",nmod);
+
+ dsa=DSA_generate_parameters(nmod,NULL,0,NULL,NULL,NULL,NULL);
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ putc('\n',stdout);
+
+ while(n--)
+ {
+ DSA_generate_key(dsa);
+
+ pbn("X",dsa->priv_key);
+ pbn("Y",dsa->pub_key);
+ putc('\n',stdout);
+ }
+ }
+ }
+ }
+
+void siggen()
+ {
+ char buf[1024];
+ int nmod=0;
+ DSA *dsa=NULL;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if(!strncmp(buf,"[mod = ",7))
+ {
+ nmod=atoi(buf+7);
+ printf("[mod = %d]\n\n",nmod);
+
+ dsa=DSA_generate_parameters(nmod,NULL,0,NULL,NULL,NULL,NULL);
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ putc('\n',stdout);
+ }
+ else if(!strncmp(buf,"Msg = ",6))
+ {
+ unsigned char msg[1024];
+ unsigned char hash[20];
+ int n;
+ DSA_SIG *sig;
+
+ n=hex2bin(buf+6,msg);
+ pv("Msg",msg,n);
+
+ DSA_generate_key(dsa);
+ pbn("Y",dsa->pub_key);
+
+ SHA1(msg,n,hash);
+ sig=DSA_do_sign(hash,sizeof hash,dsa);
+ pbn("R",sig->r);
+ pbn("S",sig->s);
+ putc('\n',stdout);
+ }
+ }
+ }
+
+void sigver()
+ {
+ DSA *dsa=NULL;
+ char buf[1024];
+ int nmod=0;
+ unsigned char hash[20];
+ DSA_SIG *sig=DSA_SIG_new();
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ if(!strncmp(buf,"[mod = ",7))
+ {
+ nmod=atoi(buf+7);
+ if(dsa)
+ DSA_free(dsa);
+ dsa=DSA_new();
+ }
+ else if(!strncmp(buf,"P = ",4))
+ dsa->p=hex2bn(buf+4);
+ else if(!strncmp(buf,"Q = ",4))
+ dsa->q=hex2bn(buf+4);
+ else if(!strncmp(buf,"G = ",4))
+ {
+ dsa->g=hex2bn(buf+4);
+
+ printf("[mod = %d]\n\n",nmod);
+ pbn("P",dsa->p);
+ pbn("Q",dsa->q);
+ pbn("G",dsa->g);
+ putc('\n',stdout);
+ }
+ else if(!strncmp(buf,"Msg = ",6))
+ {
+ unsigned char msg[1024];
+ int n;
+
+ n=hex2bin(buf+6,msg);
+ pv("Msg",msg,n);
+ SHA1(msg,n,hash);
+ }
+ else if(!strncmp(buf,"Y = ",4))
+ dsa->pub_key=hex2bn(buf+4);
+ else if(!strncmp(buf,"R = ",4))
+ sig->r=hex2bn(buf+4);
+ else if(!strncmp(buf,"S = ",4))
+ {
+ sig->s=hex2bn(buf+4);
+
+ pbn("Y",dsa->pub_key);
+ pbn("R",sig->r);
+ pbn("S",sig->s);
+ printf("Result = %c\n",DSA_do_verify(hash,sizeof hash,sig,dsa)
+ ? 'P' : 'F');
+ putc('\n',stdout);
+ }
+ }
+ }
+
+int main(int argc,char **argv)
+ {
+ if(argc != 2)
+ {
+ fprintf(stderr,"%s [prime|pqg]\n",argv[0]);
+ exit(1);
+ }
+ if(!FIPS_mode_set(1,argv[0]))
+ {
+ ERR_load_crypto_strings();
+ ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE));
+ exit(1);
+ }
+ if(!strcmp(argv[1],"prime"))
+ primes();
+ else if(!strcmp(argv[1],"pqg"))
+ pqg();
+ else if(!strcmp(argv[1],"keypair"))
+ keypair();
+ else if(!strcmp(argv[1],"siggen"))
+ siggen();
+ else if(!strcmp(argv[1],"sigver"))
+ sigver();
+ else
+ {
+ fprintf(stderr,"Don't know how to %s.\n",argv[1]);
+ exit(1);
+ }
+
+ return 0;
+ }