Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Code with split keys

  • Loading branch information...
commit 2336f8826c9cdd798711b3b21f23a64e6ef41ba6 1 parent 16eafe4
Conrad Irwin ConradIrwin authored

Showing 1 changed file with 139 additions and 3 deletions. Show diff stats Hide diff stats

  1. +139 3 minimal.c
142 minimal.c
@@ -85,7 +85,141 @@ size_t append_bignum(unsigned char *dst, const BIGNUM *value, size_t maxlen) {
85 85 return append_bytes(dst, bytes + offset, length - offset);
86 86 }
87 87
  88 +int rsa_private_encrypt(int flen, const unsigned char *from,
  89 + unsigned char *to, RSA *rsa, int padding) {
88 90
  91 +
  92 + BIGNUM *f, *ret, *res, *ret1, *ret2;
  93 + int i,j,k,num=0,r= -1;
  94 + unsigned char *buf=NULL;
  95 + BN_CTX *ctx=NULL;
  96 +
  97 + if ((ctx=BN_CTX_new()) == NULL) goto err;
  98 + BN_CTX_start(ctx);
  99 + f = BN_CTX_get(ctx);
  100 + ret = BN_CTX_get(ctx);
  101 + ret1 = BN_CTX_get(ctx);
  102 + ret2 = BN_CTX_get(ctx);
  103 + num = BN_num_bytes(rsa->n);
  104 + buf = OPENSSL_malloc(num);
  105 +
  106 + if (!f || !ret || !buf) {
  107 + printf("ERR_R_MALLOC_FAILURE");
  108 + exit(1);
  109 + }
  110 +
  111 + i = RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
  112 + if (i <= 0) goto err;
  113 +
  114 + if (BN_bin2bn(buf,num,f) == NULL) goto err;
  115 +
  116 + if (BN_ucmp(f, rsa->n) >= 0) {
  117 + /* usually the padding functions would catch this */
  118 + printf("RSA_R_DATA_TOO_LARGE_FOR_MODULUS");
  119 + exit(1);
  120 + }
  121 +
  122 + BIGNUM local_d1, local_d2;
  123 + BIGNUM *d1 = NULL, *d2 = NULL;
  124 +
  125 +
  126 + BN_init(&local_d1);
  127 + BN_init(&local_d2);
  128 + d1 = &local_d1;
  129 + d2 = &local_d2;
  130 +
  131 + BN_rand_range(d1, rsa->d);
  132 + BN_sub(d2, rsa->d, d1);
  133 +
  134 +
  135 + // TODO: is this NULL a security/performance problem?
  136 + // need to figure out what happens if rsa->flags & RSA_FLAG_CACHE_PUBLIC
  137 + // w.r.t. rsa->_method_mod_n
  138 + // TODO: re-instate CONST TIME flags and/or blinding.
  139 + if (!BN_mod_exp_mont(ret1, f, d1, rsa->n, ctx, NULL)) goto err;
  140 +
  141 + if (!BN_mod_exp_mont(ret2, f, d2, rsa->n, ctx, NULL)) goto err;
  142 +
  143 + if (!BN_mod_mul(ret, ret1, ret2, rsa->n, ctx)) goto err;
  144 +
  145 + res = ret;
  146 +
  147 + /* put in leading 0 bytes if the number is less than the
  148 + * length of the modulus */
  149 + j=BN_num_bytes(res);
  150 + i=BN_bn2bin(res,&(to[num-j]));
  151 + for (k=0; k<(num-i); k++)
  152 + to[k]=0;
  153 +
  154 + r=num;
  155 +err:
  156 + if (ctx != NULL) {
  157 + BN_CTX_end(ctx);
  158 + BN_CTX_free(ctx);
  159 + }
  160 + if (buf != NULL) {
  161 + OPENSSL_cleanse(buf,num);
  162 + OPENSSL_free(buf);
  163 + }
  164 + return(r);
  165 +}
  166 +
  167 +// Inlined from RSA_sign
  168 +int rsa_sign(int type, const unsigned char *m, unsigned int m_len,
  169 + unsigned char *sigret, unsigned int *siglen, RSA *rsa) {
  170 +
  171 + X509_SIG sig;
  172 + ASN1_TYPE parameter;
  173 + int i,j,ret=1;
  174 + unsigned char *p, *tmps = NULL;
  175 + const unsigned char *s = NULL;
  176 + X509_ALGOR algor;
  177 + ASN1_OCTET_STRING digest;
  178 +
  179 + sig.algor= &algor;
  180 + sig.algor->algorithm=OBJ_nid2obj(type);
  181 + if (sig.algor->algorithm == NULL) {
  182 + printf("RSA_R_UNKNOWN_ALGORITHM_TYPE\n");
  183 + exit(1);
  184 + }
  185 + if (sig.algor->algorithm->length == 0) {
  186 + printf("RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD\n");
  187 + exit(1);
  188 + }
  189 + parameter.type=V_ASN1_NULL;
  190 + parameter.value.ptr=NULL;
  191 + sig.algor->parameter= &parameter;
  192 +
  193 + sig.digest= &digest;
  194 + sig.digest->data=(unsigned char *)m; /* TMP UGLY CAST */
  195 + sig.digest->length=m_len;
  196 +
  197 + i=i2d_X509_SIG(&sig,NULL);
  198 + j=RSA_size(rsa);
  199 + if (i > (j-RSA_PKCS1_PADDING_SIZE)) {
  200 + printf("RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY");
  201 + exit(1);
  202 + }
  203 +
  204 + tmps=(unsigned char *)OPENSSL_malloc((unsigned int)j+1);
  205 + if (tmps == NULL) {
  206 + printf("ERR_R_MALLOC_FAILURE");
  207 + return(0);
  208 + }
  209 + p=tmps;
  210 + i2d_X509_SIG(&sig,&p);
  211 + s=tmps;
  212 +
  213 + i=rsa_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING);
  214 + if (i <= 0)
  215 + ret=0;
  216 + else
  217 + *siglen=i;
  218 +
  219 + OPENSSL_cleanse(tmps,(unsigned int)j+1);
  220 + OPENSSL_free(tmps);
  221 + return(ret);
  222 +}
89 223 /* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1, based on OpenSSH.
90 224 * Note from RFC3447:
91 225 * Although no attacks are known against RSASSA-PKCS1-v1_5, in the interest of
@@ -101,11 +235,13 @@ void ssh_rsa_sign(const EVP_PKEY *key, unsigned char *sig_r, unsigned int *len_r
101 235 EVP_DigestUpdate(&md, data, datalen);
102 236 EVP_DigestFinal(&md, digest, &dlen);
103 237
104   - RSA *rsa = EVP_PKEY_get1_RSA(key);
  238 + RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key);
105 239 unsigned int slen = RSA_size(rsa);
106 240
107   - if (RSA_sign(NID_sha1, digest, dlen, sig, &len, rsa) != 1) {
108   - fprintf(stderr, "RSA_sign failed: %s\n", ERR_error_string(ERR_get_error(), NULL));
  241 + if (rsa_sign(NID_sha1, digest, dlen, sig, &len, rsa) != 1) {
  242 + char errbuf[8096];
  243 + ERR_error_string_n(ERR_get_error(), errbuf, 8096);
  244 + fprintf(stderr, "RSA_sign failed: %s\n", errbuf);
109 245 exit(1);
110 246 }
111 247 if (len < slen) {

0 comments on commit 2336f88

Please sign in to comment.
Something went wrong with that request. Please try again.