diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/rsa/rsa_pk1.c (renamed from src/lib/libssl/src/fips-1.0/dh/fips_dh_gen.c) | 240 |
1 files changed, 139 insertions, 101 deletions
diff --git a/src/lib/libssl/src/fips-1.0/dh/fips_dh_gen.c b/src/lib/libcrypto/rsa/rsa_pk1.c index b569e3912d..8560755f1d 100644 --- a/src/lib/libssl/src/fips-1.0/dh/fips_dh_gen.c +++ b/src/lib/libcrypto/rsa/rsa_pk1.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* crypto/dh/dh_gen.c */ | 1 | /* crypto/rsa/rsa_pk1.c */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -57,130 +57,168 @@ | |||
| 57 | */ | 57 | */ |
| 58 | 58 | ||
| 59 | #include <stdio.h> | 59 | #include <stdio.h> |
| 60 | #include <string.h> | 60 | #include "cryptlib.h" |
| 61 | #include <openssl/err.h> | ||
| 62 | #include <openssl/bn.h> | 61 | #include <openssl/bn.h> |
| 63 | #ifndef OPENSSL_NO_DH | 62 | #include <openssl/rsa.h> |
| 64 | #include <openssl/dh.h> | 63 | #include <openssl/rand.h> |
| 65 | #endif | ||
| 66 | #include <openssl/fips.h> | ||
| 67 | |||
| 68 | #ifndef OPENSSL_NO_DH | ||
| 69 | #ifdef OPENSSL_FIPS | ||
| 70 | |||
| 71 | /* We generate DH parameters as follows | ||
| 72 | * find a prime q which is prime_len/2 bits long. | ||
| 73 | * p=(2*q)+1 or (p-1)/2 = q | ||
| 74 | * For this case, g is a generator if | ||
| 75 | * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. | ||
| 76 | * Since the factors of p-1 are q and 2, we just need to check | ||
| 77 | * g^2 mod p != 1 and g^q mod p != 1. | ||
| 78 | * | ||
| 79 | * Having said all that, | ||
| 80 | * there is another special case method for the generators 2, 3 and 5. | ||
| 81 | * for 2, p mod 24 == 11 | ||
| 82 | * for 3, p mod 12 == 5 <<<<< does not work for safe primes. | ||
| 83 | * for 5, p mod 10 == 3 or 7 | ||
| 84 | * | ||
| 85 | * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the | ||
| 86 | * special generators and for answering some of my questions. | ||
| 87 | * | ||
| 88 | * I've implemented the second simple method :-). | ||
| 89 | * Since DH should be using a safe prime (both p and q are prime), | ||
| 90 | * this generator function can take a very very long time to run. | ||
| 91 | */ | ||
| 92 | /* Actually there is no reason to insist that 'generator' be a generator. | ||
| 93 | * It's just as OK (and in some sense better) to use a generator of the | ||
| 94 | * order-q subgroup. | ||
| 95 | */ | ||
| 96 | 64 | ||
| 97 | DH *DH_generate_parameters(int prime_len, int generator, | 65 | int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, |
| 98 | void (*callback)(int,int,void *), void *cb_arg) | 66 | const unsigned char *from, int flen) |
| 99 | { | 67 | { |
| 100 | BIGNUM *p=NULL,*t1,*t2; | 68 | int j; |
| 101 | DH *ret=NULL; | 69 | unsigned char *p; |
| 102 | int g,ok= -1; | ||
| 103 | BN_CTX *ctx=NULL; | ||
| 104 | 70 | ||
| 105 | if(FIPS_selftest_failed()) | 71 | if (flen > (tlen-RSA_PKCS1_PADDING_SIZE)) |
| 106 | { | 72 | { |
| 107 | FIPSerr(FIPS_F_DH_GENERATE_PARAMETERS,FIPS_R_FIPS_SELFTEST_FAILED); | 73 | RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); |
| 108 | return NULL; | 74 | return(0); |
| 109 | } | 75 | } |
| 110 | |||
| 111 | ret=DH_new(); | ||
| 112 | if (ret == NULL) goto err; | ||
| 113 | ctx=BN_CTX_new(); | ||
| 114 | if (ctx == NULL) goto err; | ||
| 115 | BN_CTX_start(ctx); | ||
| 116 | t1 = BN_CTX_get(ctx); | ||
| 117 | t2 = BN_CTX_get(ctx); | ||
| 118 | if (t1 == NULL || t2 == NULL) goto err; | ||
| 119 | 76 | ||
| 120 | if (generator <= 1) | 77 | p=(unsigned char *)to; |
| 78 | |||
| 79 | *(p++)=0; | ||
| 80 | *(p++)=1; /* Private Key BT (Block Type) */ | ||
| 81 | |||
| 82 | /* pad out with 0xff data */ | ||
| 83 | j=tlen-3-flen; | ||
| 84 | memset(p,0xff,j); | ||
| 85 | p+=j; | ||
| 86 | *(p++)='\0'; | ||
| 87 | memcpy(p,from,(unsigned int)flen); | ||
| 88 | return(1); | ||
| 89 | } | ||
| 90 | |||
| 91 | int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, | ||
| 92 | const unsigned char *from, int flen, int num) | ||
| 93 | { | ||
| 94 | int i,j; | ||
| 95 | const unsigned char *p; | ||
| 96 | |||
| 97 | p=from; | ||
| 98 | if ((num != (flen+1)) || (*(p++) != 01)) | ||
| 121 | { | 99 | { |
| 122 | DHerr(DH_F_DH_GENERATE_PARAMETERS, DH_R_BAD_GENERATOR); | 100 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BLOCK_TYPE_IS_NOT_01); |
| 123 | goto err; | 101 | return(-1); |
| 124 | } | 102 | } |
| 125 | if (generator == DH_GENERATOR_2) | 103 | |
| 104 | /* scan over padding data */ | ||
| 105 | j=flen-1; /* one for type. */ | ||
| 106 | for (i=0; i<j; i++) | ||
| 126 | { | 107 | { |
| 127 | if (!BN_set_word(t1,24)) goto err; | 108 | if (*p != 0xff) /* should decrypt to 0xff */ |
| 128 | if (!BN_set_word(t2,11)) goto err; | 109 | { |
| 129 | g=2; | 110 | if (*p == 0) |
| 111 | { p++; break; } | ||
| 112 | else { | ||
| 113 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_FIXED_HEADER_DECRYPT); | ||
| 114 | return(-1); | ||
| 115 | } | ||
| 116 | } | ||
| 117 | p++; | ||
| 130 | } | 118 | } |
| 131 | #if 0 /* does not work for safe primes */ | 119 | |
| 132 | else if (generator == DH_GENERATOR_3) | 120 | if (i == j) |
| 133 | { | 121 | { |
| 134 | if (!BN_set_word(t1,12)) goto err; | 122 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_NULL_BEFORE_BLOCK_MISSING); |
| 135 | if (!BN_set_word(t2,5)) goto err; | 123 | return(-1); |
| 136 | g=3; | ||
| 137 | } | 124 | } |
| 138 | #endif | 125 | |
| 139 | else if (generator == DH_GENERATOR_5) | 126 | if (i < 8) |
| 140 | { | 127 | { |
| 141 | if (!BN_set_word(t1,10)) goto err; | 128 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_BAD_PAD_BYTE_COUNT); |
| 142 | if (!BN_set_word(t2,3)) goto err; | 129 | return(-1); |
| 143 | /* BN_set_word(t3,7); just have to miss | ||
| 144 | * out on these ones :-( */ | ||
| 145 | g=5; | ||
| 146 | } | 130 | } |
| 147 | else | 131 | i++; /* Skip over the '\0' */ |
| 132 | j-=i; | ||
| 133 | if (j > tlen) | ||
| 148 | { | 134 | { |
| 149 | /* in the general case, don't worry if 'generator' is a | 135 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1,RSA_R_DATA_TOO_LARGE); |
| 150 | * generator or not: since we are using safe primes, | 136 | return(-1); |
| 151 | * it will generate either an order-q or an order-2q group, | ||
| 152 | * which both is OK */ | ||
| 153 | if (!BN_set_word(t1,2)) goto err; | ||
| 154 | if (!BN_set_word(t2,1)) goto err; | ||
| 155 | g=generator; | ||
| 156 | } | 137 | } |
| 138 | memcpy(to,p,(unsigned int)j); | ||
| 139 | |||
| 140 | return(j); | ||
| 141 | } | ||
| 142 | |||
| 143 | int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, | ||
| 144 | const unsigned char *from, int flen) | ||
| 145 | { | ||
| 146 | int i,j; | ||
| 147 | unsigned char *p; | ||
| 157 | 148 | ||
| 158 | p=BN_generate_prime(NULL,prime_len,1,t1,t2,callback,cb_arg); | 149 | if (flen > (tlen-11)) |
| 159 | if (p == NULL) goto err; | ||
| 160 | if (callback != NULL) callback(3,0,cb_arg); | ||
| 161 | ret->p=p; | ||
| 162 | ret->g=BN_new(); | ||
| 163 | if (!BN_set_word(ret->g,g)) goto err; | ||
| 164 | ok=1; | ||
| 165 | err: | ||
| 166 | if (ok == -1) | ||
| 167 | { | 150 | { |
| 168 | DHerr(DH_F_DH_GENERATE_PARAMETERS,ERR_R_BN_LIB); | 151 | RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); |
| 169 | ok=0; | 152 | return(0); |
| 170 | } | 153 | } |
| 154 | |||
| 155 | p=(unsigned char *)to; | ||
| 171 | 156 | ||
| 172 | if (ctx != NULL) | 157 | *(p++)=0; |
| 158 | *(p++)=2; /* Public Key BT (Block Type) */ | ||
| 159 | |||
| 160 | /* pad out with non-zero random data */ | ||
| 161 | j=tlen-3-flen; | ||
| 162 | |||
| 163 | if (RAND_bytes(p,j) <= 0) | ||
| 164 | return(0); | ||
| 165 | for (i=0; i<j; i++) | ||
| 173 | { | 166 | { |
| 174 | BN_CTX_end(ctx); | 167 | if (*p == '\0') |
| 175 | BN_CTX_free(ctx); | 168 | do { |
| 169 | if (RAND_bytes(p,1) <= 0) | ||
| 170 | return(0); | ||
| 171 | } while (*p == '\0'); | ||
| 172 | p++; | ||
| 176 | } | 173 | } |
| 177 | if (!ok && (ret != NULL)) | 174 | |
| 175 | *(p++)='\0'; | ||
| 176 | |||
| 177 | memcpy(p,from,(unsigned int)flen); | ||
| 178 | return(1); | ||
| 179 | } | ||
| 180 | |||
| 181 | int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, | ||
| 182 | const unsigned char *from, int flen, int num) | ||
| 183 | { | ||
| 184 | int i,j; | ||
| 185 | const unsigned char *p; | ||
| 186 | |||
| 187 | p=from; | ||
| 188 | if ((num != (flen+1)) || (*(p++) != 02)) | ||
| 178 | { | 189 | { |
| 179 | DH_free(ret); | 190 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BLOCK_TYPE_IS_NOT_02); |
| 180 | ret=NULL; | 191 | return(-1); |
| 181 | } | 192 | } |
| 182 | return(ret); | 193 | #ifdef PKCS1_CHECK |
| 194 | return(num-11); | ||
| 195 | #endif | ||
| 196 | |||
| 197 | /* scan over padding data */ | ||
| 198 | j=flen-1; /* one for type. */ | ||
| 199 | for (i=0; i<j; i++) | ||
| 200 | if (*(p++) == 0) break; | ||
| 201 | |||
| 202 | if (i == j) | ||
| 203 | { | ||
| 204 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_NULL_BEFORE_BLOCK_MISSING); | ||
| 205 | return(-1); | ||
| 206 | } | ||
| 207 | |||
| 208 | if (i < 8) | ||
| 209 | { | ||
| 210 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_BAD_PAD_BYTE_COUNT); | ||
| 211 | return(-1); | ||
| 212 | } | ||
| 213 | i++; /* Skip over the '\0' */ | ||
| 214 | j-=i; | ||
| 215 | if (j > tlen) | ||
| 216 | { | ||
| 217 | RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2,RSA_R_DATA_TOO_LARGE); | ||
| 218 | return(-1); | ||
| 219 | } | ||
| 220 | memcpy(to,p,(unsigned int)j); | ||
| 221 | |||
| 222 | return(j); | ||
| 183 | } | 223 | } |
| 184 | 224 | ||
| 185 | #endif | ||
| 186 | #endif | ||
