/** Non-complex part (no primality testing) of the validation of DSA params (p, q, g) @param key The key to validate @param stat [out] Result of test, 1==valid, 0==invalid @return CRYPT_OK if successful */ int dsa_int_validate_pqg(dsa_key *key, int *stat) { void *tmp1, *tmp2; int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(stat != NULL); *stat = 0; /* check q-order */ if ( key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 || (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA ) { return CRYPT_OK; } /* FIPS 186-4 chapter 4.1: 1 < g < p */ if (mp_cmp_d(key->g, 1) != LTC_MP_GT || mp_cmp(key->g, key->p) != LTC_MP_LT) { return CRYPT_OK; } if ((err = mp_init_multi(&tmp1, &tmp2, NULL)) != CRYPT_OK) { return err; } /* FIPS 186-4 chapter 4.1: q is a divisor of (p - 1) */ if ((err = mp_sub_d(key->p, 1, tmp1)) != CRYPT_OK) { goto error; } if ((err = mp_div(tmp1, key->q, tmp1, tmp2)) != CRYPT_OK) { goto error; } if (mp_iszero(tmp2) != LTC_MP_YES) { err = CRYPT_OK; goto error; } /* FIPS 186-4 chapter 4.1: g is a generator of a subgroup of order q in * the multiplicative group of GF(p) - so we make sure that g^q mod p = 1 */ if ((err = mp_exptmod(key->g, key->q, key->p, tmp1)) != CRYPT_OK) { goto error; } if (mp_cmp_d(tmp1, 1) != LTC_MP_EQ) { err = CRYPT_OK; goto error; } err = CRYPT_OK; *stat = 1; error: mp_clear_multi(tmp2, tmp1, NULL); return err; }
unsigned int BigInteger::length() const { int rc = mp_unsigned_bin_size(const_cast<mp_int*>(&t)); if (rc < 0) { check(rc, "mp_unsigned_bin_size(&t)"); } return static_cast<unsigned int>(rc); }
int mp_pkcs1v15_maxlen(mp_int *modulus) { int modlen = mp_unsigned_bin_size(modulus); if(modlen < 10) return 0; else return modlen - 10; } /* end mp_pkcs1v15_maxlen() */
static void GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz) { word32 sz = mp_unsigned_bin_size(&key->p); sz = min(sz, 2 * DiscreteLogWorkFactor(sz * BIT_SIZE) / BIT_SIZE + 1); RNG_GenerateBlock(rng, priv, sz); priv[0] |= 0x0C; *privSz = sz; }
/** Simple RSA decryption @param sig The signature data @param siglen The length of the signature data (octets) @param hash The hash of the message that was signed @param hashlen The length of the hash of the message that was signed (octets) @param stat [out] The result of the signature comparison, 1==valid, 0==invalid @param key The public RSA key corresponding @return Error code */ int rsa_verify_simple(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; unsigned char *tmpbuf; int err; LTC_ARGCHK(sig != NULL); LTC_ARGCHK(hash != NULL); LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); /* default to invalid */ *stat = 0; /* get modulus len in bits */ modulus_bitlen = mp_count_bits( (key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size( (key->N)); if (modulus_bytelen != siglen) { return CRYPT_INVALID_PACKET; } /* allocate temp buffer for decoded sig */ tmpbuf = XMALLOC(siglen); if (tmpbuf == NULL) { return CRYPT_MEM; } /* RSA decode it */ x = siglen; if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { XFREE(tmpbuf); return err; } /* make sure the output is the right size */ if (x != siglen) { XFREE(tmpbuf); return CRYPT_INVALID_PACKET; } /* compare the decrypted signature with the given hash */ if (x == hashlen && XMEMCMP(tmpbuf, hash, hashlen) == 0) *stat = 1; #ifdef LTC_CLEAN_STACK zeromem(tmpbuf, siglen); #endif XFREE(tmpbuf); return CRYPT_OK; }
/** ECC X9.63 (Sec. 4.3.6) uncompressed export @param key Key to export @param out [out] destination of export @param outlen [in/out] Length of destination and final output size Return CRYPT_OK on success */ int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen) { unsigned char buf[ECC_BUF_SIZE]; unsigned long numlen, xlen, ylen; LTC_ARGCHK(key != NULL); LTC_ARGCHK(outlen != NULL); if (ltc_ecc_is_valid_idx(key->idx) == 0) { return CRYPT_INVALID_ARG; } numlen = key->dp->size; xlen = mp_unsigned_bin_size(key->pubkey.x); ylen = mp_unsigned_bin_size(key->pubkey.y); if (xlen > numlen || ylen > numlen || sizeof(buf) < numlen) { return CRYPT_BUFFER_OVERFLOW; } if (*outlen < (1 + 2*numlen)) { *outlen = 1 + 2*numlen; return CRYPT_BUFFER_OVERFLOW; } LTC_ARGCHK(out != NULL); /* store byte 0x04 */ out[0] = 0x04; /* pad and store x */ zeromem(buf, sizeof(buf)); mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - xlen)); XMEMCPY(out+1, buf, numlen); /* pad and store y */ zeromem(buf, sizeof(buf)); mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - ylen)); XMEMCPY(out+1+numlen, buf, numlen); *outlen = 1 + 2*numlen; return CRYPT_OK; }
mp_err mp_pkcs1v15_encrypt(char *msg, int mlen, mp_int *e, mp_int *modulus, char **out, int *olen, rnd_f rand) { int k; char *buf; mp_err res; mp_int mrep; ARGCHK(msg != NULL && mlen >= 0 && e != NULL && modulus != NULL && out != NULL && olen != NULL, MP_BADARG); k = mp_unsigned_bin_size(modulus); /* length of modulus, in bytes */ if((buf = malloc(k)) == NULL) return MP_MEM; /* Encode according to PKCS #1 v1.5 */ if((res = mp_pkcs1v15_encode(msg, mlen, buf, k, rand)) != MP_OKAY) goto CLEANUP; /* Convert encoded message to a big number for encryption */ if((res = mp_init(&mrep)) != MP_OKAY) goto CLEANUP; if((res = mp_os2ip(&mrep, buf, k)) != MP_OKAY) { mp_clear(&mrep); goto CLEANUP; } /* Now, encrypt... */ if((res = mp_rsaep(&mrep, e, modulus, &mrep)) != MP_OKAY) { mp_clear(&mrep); goto CLEANUP; } /* Unpack message representative... */ if((res = mp_i2osp(&mrep, buf, k)) != MP_OKAY) { mp_clear(&mrep); goto CLEANUP; } mp_clear(&mrep); *out = buf; *olen = k; return MP_OKAY; CLEANUP: memset(buf, 0, k); free(buf); return res; } /* end mp_pkcs1v15_encrypt() */
static void GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz) { word32 sz = mp_unsigned_bin_size(&key->p); /* Disabled on request for WPS in WMSDK. Seems that this is not required */ /* sz = min(sz, 2 * DiscreteLogWorkFactor(sz * CYASSL_BIT_SIZE) / CYASSL_BIT_SIZE + 1); */ RNG_GenerateBlock(rng, priv, sz); priv[0] |= 0x0C; *privSz = sz; }
/** Retrieve the size in bytes of an RSA key. @param key The RSA key @return The size in bytes of the RSA key or INT_MAX on error. */ int rsa_get_size(rsa_key *key) { int ret = INT_MAX; LTC_ARGCHK(key != NULL); if (key) { ret = mp_unsigned_bin_size(key->N); } /* if */ return ret; }
/** LTC_PKCS #1 Integer to binary @param n The integer to store @param modulus_len The length of the RSA modulus @param out [out] The destination for the integer @return CRYPT_OK if successful */ int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out) { unsigned long size; size = mp_unsigned_bin_size(n); if (size > modulus_len) { return CRYPT_BUFFER_OVERFLOW; } /* store it */ zeromem(out, modulus_len); return mp_to_unsigned_bin(n, out + (modulus_len - size)); }
/** (PKCS #1 v2.0) decrypt then OAEP depad @param in The ciphertext @param inlen The length of the ciphertext (octets) @param out [out] The plaintext @param outlen [in/out] The max size and resulting size of the plaintext (octets) @param lparam The system "lparam" value @param lparamlen The length of the lparam value (octets) @param hash_idx The index of the hash desired @param stat [out] Result of the decryption, 1==valid, 0==invalid @param key The corresponding private RSA key @return CRYPT_OK if succcessul (even if invalid) */ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, int hash_idx, int *stat, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmp; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(stat != NULL); /* default to invalid */ *stat = 0; /* valid hash ? */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits( (key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size( (key->N)); if (modulus_bytelen != inlen) { return CRYPT_INVALID_PACKET; } /* allocate ram */ tmp = XMALLOC(inlen); if (tmp == NULL) { return CRYPT_MEM; } /* rsa decode the packet */ x = inlen; if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { XFREE(tmp); return err; } /* now OAEP decode the packet */ err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx, out, outlen, stat); XFREE(tmp); return err; }
/** Gets length of DER encoding of num @param num The int to get the size of @param outlen [out] The length of the DER encoding for the given integer @return CRYPT_OK if successful */ int der_length_integer(void *num, unsigned long *outlen) { unsigned long z, len; int leading_zero; LTC_ARGCHK(num != NULL); LTC_ARGCHK(outlen != NULL); if (mp_cmp_d(num, 0) != LTC_MP_LT) { /* positive */ /* we only need a leading zero if the msb of the first byte is one */ if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { leading_zero = 1; } else { leading_zero = 0; } /* size for bignum */ z = len = leading_zero + mp_unsigned_bin_size(num); } else { /* it's negative */ /* find power of 2 that is a multiple of eight and greater than count bits */ leading_zero = 0; z = mp_count_bits(num); z = z + (8 - (z & 7)); if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z; len = z = z >> 3; } /* now we need a length */ if (z < 128) { /* short form */ ++len; } else { /* long form (relies on z != 0), assumes length bytes < 128 */ ++len; while (z) { ++len; z >>= 8; } } /* we need a 0x02 to indicate it's INTEGER */ ++len; /* return length */ *outlen = len; return CRYPT_OK; }
/** Create a DSA shared secret between two keys @param private_key The private DSA key (the exponent) @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt) @param public_key The public key @param out [out] Destination of the shared secret @param outlen [in/out] The max size and resulting size of the shared secret @return CRYPT_OK if successful */ int dsa_shared_secret(void *private_key, void *base, dsa_key *public_key, unsigned char *out, unsigned long *outlen) { unsigned long x; void *res; int err; LTC_ARGCHK(private_key != NULL); LTC_ARGCHK(public_key != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* make new point */ if ((err = mp_init(&res)) != CRYPT_OK) { return err; } if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) { mp_clear(res); return err; } x = (unsigned long)mp_unsigned_bin_size(res); if (*outlen < x) { *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto done; } zeromem(out, x); if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; } err = CRYPT_OK; *outlen = x; done: mp_clear(res); return err; }
OK_RESULT ok_load_user_rsa(unsigned long __user arg) { int len; copy_from_user(&len, (void *)arg, 4); char *tmp= (char *)kmalloc(len+5, GFP_KERNEL); copy_from_user(tmp, (void *)(arg), len+4); tmp[len+4] = '\0'; /* read the passwd to protect user root key */ int pass_len; unsigned char passwd[OK_MAX_PASSWD_LEN]; copy_from_user(&pass_len, (void *)(arg+len+4), 4); copy_from_user(passwd, (void *)(arg+len+8), pass_len); unsigned char hash[OK_BIN_HASH_LEN]; int hashlen = OK_BIN_HASH_LEN; ok_make_hash(passwd, pass_len, hash, &hashlen); char *filename = tmp + 4; rsa_key * user_key; ok_create_key(&user_key); unsigned char *blob = (unsigned char *)kmalloc(mp_unsigned_bin_size(&(user_key->N)) * 20, GFP_KERNEL); ok_load_blob(blob, filename); *((int *) blob) -= OK_BIN_HASH_LEN; if(memcmp(hash, blob+(*((int *)blob))+4, OK_BIN_HASH_LEN) != 0) { ok_free_rsa_key(&user_key); int ret = -1; copy_to_user((void *)arg, &ret, sizeof(rsa_key *)); return OK_VALUE_ERROR; } ok_decrypt_rsa_by_srk(user_key, blob); copy_to_user((void *)arg, &user_key, sizeof(rsa_key *)); kfree(blob); kfree(tmp); return OK_SUCCESS; }
/** Store a mp_int integer @param num The first mp_int to encode @param out [out] The destination for the DER encoded integers @param outlen [in/out] The max size and resulting size of the DER encoded integers @return CRYPT_OK if successful */ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) { unsigned long tmplen, y; int err, leading_zero; LTC_ARGCHK(num != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* find out how big this will be */ if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) { return err; } if (*outlen < tmplen) { *outlen = tmplen; return CRYPT_BUFFER_OVERFLOW; } if (mp_cmp_d(num, 0) != LTC_MP_LT) { /* we only need a leading zero if the msb of the first byte is one */ if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { leading_zero = 1; } else { leading_zero = 0; } /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ y = mp_unsigned_bin_size(num) + leading_zero; } else { leading_zero = 0; y = mp_count_bits(num); y = y + (8 - (y & 7)); y = y >> 3; if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y; } /* now store initial data */ *out++ = 0x02; if (y < 128) { /* short form */ *out++ = (unsigned char)y; } else if (y < 256) { *out++ = 0x81; *out++ = (unsigned char)y; } else if (y < 65536UL) { *out++ = 0x82; *out++ = (unsigned char)((y>>8)&255); *out++ = (unsigned char)y; } else if (y < 16777216UL) {
/** * bignum_get_unsigned_bin - Set binary buffer to unsigned bignum * @n: Bignum from bignum_init() * @buf: Buffer for the binary number * @len: Length of the buffer, can be %NULL if buffer is known to be long * enough. Set to used buffer length on success if not %NULL. * Returns: 0 on success, -1 on failure */ int bignum_get_unsigned_bin(const struct bignum *n, u8 *buf, size_t *len) { size_t need = mp_unsigned_bin_size((mp_int *) n); if (len && need > *len) { *len = need; return -1; } if (mp_to_unsigned_bin((mp_int *) n, buf) != MP_OKAY) { wpa_printf(MSG_DEBUG, "BIGNUM: %s failed", __func__); return -1; } if (len) *len = need; return 0; }
/** (PKCS #1, v2.0) de-sign then PSS depad @param sig The signature data @param siglen The length of the signature data (octets) @param hash The hash of the message that was signed @param hashlen The length of the hash of the message that was signed (octets) @param hash_idx The index of the desired hash @param saltlen The length of the salt used during signature @param stat [out] The result of the signature comparison, 1==valid, 0==invalid @param key The public RSA key corresponding to the key that performed the signature @return CRYPT_OK on success (even if the signature is invalid) */ int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int hash_idx, unsigned long saltlen, int *stat, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmpbuf; LTC_ARGCHK(hash != NULL); LTC_ARGCHK(sig != NULL); LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); /* default to invalid */ *stat = 0; /* valid hash ? */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits(&(key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size(&(key->N)); if (modulus_bytelen != siglen) { return CRYPT_INVALID_PACKET; } /* allocate temp buffer for decoded sig */ tmpbuf = XMALLOC(siglen); if (tmpbuf == NULL) { return CRYPT_MEM; } /* RSA decode it */ x = siglen; if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { XFREE(tmpbuf); return err; } /* PSS decode it */ err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); XFREE(tmpbuf); return err; }
int wc_mp_to_bigint(mp_int* src, WC_BIGINT* dst) { int err; word32 sz; if (src == NULL || dst == NULL) return BAD_FUNC_ARG; sz = mp_unsigned_bin_size(src); err = wc_bigint_alloc(dst, sz); if (err == MP_OKAY) err = mp_to_unsigned_bin(src, dst->buf); return err; }
static int32 psAsnParsePrivateKey(psPool_t *pool, unsigned char **pp, int32 size, sslRsaKey_t *key) { unsigned char *p, *end, *seq; int32 version, seqlen; key->optimized = 0; p = *pp; end = p + size; if (getSequence(&p, size, &seqlen) < 0) { matrixStrDebugMsg("ASN sequence parse error\n", NULL); return -1; } seq = p; if (getInteger(&p, (int32)(end - p), &version) < 0 || version != 0 || getBig(pool, &p, (int32)(end - p), &(key->N)) < 0 || mp_shrink(&key->N) != MP_OKAY || getBig(pool, &p, (int32)(end - p), &(key->e)) < 0 || mp_shrink(&key->e) != MP_OKAY || getBig(pool, &p, (int32)(end - p), &(key->d)) < 0 || mp_shrink(&key->d) != MP_OKAY || getBig(pool, &p, (int32)(end - p), &(key->p)) < 0 || mp_shrink(&key->p) != MP_OKAY || getBig(pool, &p, (int32)(end - p), &(key->q)) < 0 || mp_shrink(&key->q) != MP_OKAY || getBig(pool, &p, (int32)(end - p), &(key->dP)) < 0 || mp_shrink(&key->dP) != MP_OKAY || getBig(pool, &p, (int32)(end - p), &(key->dQ)) < 0 || mp_shrink(&key->dQ) != MP_OKAY || getBig(pool, &p, (int32)(end - p), &(key->qP)) < 0 || mp_shrink(&key->qP) != MP_OKAY || (int32)(p - seq) != seqlen) { matrixStrDebugMsg("ASN key extract parse error\n", NULL); return -1; } /* If we made it here, the key is ready for optimized decryption */ key->optimized = 1; *pp = p; /* Set the key length of the key */ key->size = mp_unsigned_bin_size(&key->N); return 0; }
/** (LTC_PKCS #1 v2.0) OAEP pad then encrypt @param in The plaintext @param inlen The length of the plaintext (octets) @param out [out] The ciphertext @param outlen [in/out] The max size and resulting size of the ciphertext @param lparam The system "lparam" for the encryption @param lparamlen The length of lparam (octets) @param prng An active PRNG @param prng_idx The index of the desired prng @param hash_idx The index of the desired hash @param key The Katja key to encrypt to @return CRYPT_OK if successful */ int katja_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, int hash_idx, katja_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* valid prng and hash ? */ if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits((key->N)); /* payload is upto pq, so we know q is 1/3rd the size of N and therefore pq is 2/3th the size */ modulus_bitlen = ((modulus_bitlen << 1) / 3); /* round down to next byte */ modulus_bitlen -= (modulus_bitlen & 7) + 8; /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size((key->N)); if (modulus_bytelen > *outlen) { *outlen = modulus_bytelen; return CRYPT_BUFFER_OVERFLOW; } /* OAEP pad the key */ x = *outlen; if ((err = pkcs_1_oaep_encode(in, inlen, lparam, lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, out, &x)) != CRYPT_OK) { return err; } /* Katja exptmod the OAEP pad */ return katja_exptmod(out, x, out, outlen, PK_PUBLIC, key); }
mp_err mp_pkcs1v15_decrypt(char *msg, int mlen, mp_int *d, mp_int *modulus, char **out, int *olen) { int k; char *buf; mp_err res; mp_int mrep; ARGCHK(msg != NULL && d != NULL && modulus != NULL && out != NULL && olen != NULL, MP_BADARG); k = mp_unsigned_bin_size(modulus); /* size of modulus, in bytes */ if(mlen != k) return MP_UNDEF; if((buf = malloc(k)) == NULL) return MP_MEM; /* Convert ciphertext to integer representative */ if((res = mp_init(&mrep)) != MP_OKAY) { free(buf); return res; } if((res = mp_os2ip(&mrep, msg, mlen)) != MP_OKAY) goto CLEANUP; /* Decrypt ... */ if((res = mp_rsadp(&mrep, d, modulus, &mrep)) != MP_OKAY) goto CLEANUP; if((res = mp_i2osp(&mrep, buf, k)) != MP_OKAY) goto CLEANUP; if((res = mp_pkcs1v15_decode(buf, k, buf, olen)) == MP_OKAY) { *out = buf; return MP_OKAY; } CLEANUP: memset(buf, 0, k - 1); free(buf); mp_clear(&mrep); return res; } /* end mp_pkcs1v15_decrypt() */
static BIGNUM * mpz2BN(mp_int *s) { size_t size; BIGNUM *bn; void *p; size = mp_unsigned_bin_size(s); p = malloc(size); if (p == NULL && size != 0) return NULL; mp_to_unsigned_bin(s, p); bn = BN_bin2bn(p, size, NULL); free(p); return bn; }
static int GeneratePrivate(DhKey* key, RNG* rng, byte* priv, word32* privSz) { int ret; word32 sz = mp_unsigned_bin_size(&key->p); sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1); ret = wc_RNG_GenerateBlock(rng, priv, sz); if (ret != 0) return ret; priv[0] |= 0x0C; *privSz = sz; return 0; }
/* always stores the same # of bytes, pads with leading zero bytes as required */ int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out) { int err; unsigned long size; size = mp_unsigned_bin_size(n); if (size > modulus_len) { return CRYPT_BUFFER_OVERFLOW; } /* store it */ zeromem(out, modulus_len); if ((err = mp_to_unsigned_bin(n, out+(modulus_len-size))) != MP_OKAY) { return mpi_to_ltc_error(err); } return CRYPT_OK; }
/* for Rsa Sign */ int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key, RNG* rng) { int sz = mp_unsigned_bin_size(&key->n), ret; if (sz > (int)outLen) return RSA_BUFFER_E; if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) return RSA_BUFFER_E; RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng); if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PRIVATE_ENCRYPT,key)) < 0) sz = ret; return sz; }
mp_err mp_i2osp(mp_int *x, char *out, int len) { int xlen; ARGCHK(x != NULL && out != NULL && len > 0, MP_BADARG); if((xlen = mp_unsigned_bin_size(x)) > len) { return MP_RANGE; } xlen -= len; if(xlen > 0) memset(out, 0, xlen); mp_to_unsigned_bin(x, (unsigned char *)out + xlen); return MP_OKAY; } /* end mp_i2osp() */
/** (PKCS #1, v2.0) PSS pad then sign @param in The hash to sign @param inlen The length of the hash to sign (octets) @param out [out] The signature @param outlen [in/out] The max size and resulting size of the signature @param prng An active PRNG state @param prng_idx The index of the PRNG desired @param hash_idx The index of the hash desired @param saltlen The length of the salt desired (octets) @param key The private RSA key to use @return CRYPT_OK if successful */ int rsa_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int prng_idx, int hash_idx, unsigned long saltlen, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* valid prng and hash ? */ if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits(&(key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size(&(key->N)); if (modulus_bytelen > *outlen) { return CRYPT_BUFFER_OVERFLOW; } /* PSS pad the key */ x = *outlen; if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx, hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { return err; } /* RSA encode it */ return rsa_exptmod(out, x, out, outlen, PK_PRIVATE, key); }
/** (PKCS #1 v2.0) OAEP pad then encrypt @param in The plaintext @param inlen The length of the plaintext (octets) @param out [out] The ciphertext @param outlen [in/out] The max size and resulting size of the ciphertext @param lparam The system "lparam" for the encryption @param lparamlen The length of lparam (octets) @param prng An active PRNG @param prng_idx The index of the desired prng @param hash_idx The index of the desired hash @param key The RSA key to encrypt to @return CRYPT_OK if successful */ int rsa_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, int hash_idx, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* valid prng and hash ? */ if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits(&(key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size(&(key->N)); if (modulus_bytelen > *outlen) { return CRYPT_BUFFER_OVERFLOW; } /* OAEP pad the key */ x = *outlen; if ((err = pkcs_1_oaep_encode(in, inlen, lparam, lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, out, &x)) != CRYPT_OK) { return err; } /* rsa exptmod the OAEP pad */ return rsa_exptmod(out, x, out, outlen, PK_PUBLIC, key); }
static int GeneratePrivate(DhKey* key, WC_RNG* rng, byte* priv, word32* privSz) { int ret; word32 sz = mp_unsigned_bin_size(&key->p); /* Table of predetermined values from the operation 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1 Sizes in table checked against RFC 3526 */ WOLFSSL_DH_ROUND(sz); /* if using fixed points only, then round up */ switch (sz) { case 128: sz = 21; break; case 256: sz = 29; break; case 384: sz = 34; break; case 512: sz = 39; break; case 640: sz = 42; break; case 768: sz = 46; break; case 896: sz = 49; break; case 1024: sz = 52; break; default: #ifndef WOLFSSL_DH_CONST /* if using floating points and size of p is not in table */ sz = min(sz, 2 * DiscreteLogWorkFactor(sz * WOLFSSL_BIT_SIZE) / WOLFSSL_BIT_SIZE + 1); break; #else return BAD_FUNC_ARG; #endif } ret = wc_RNG_GenerateBlock(rng, priv, sz); if (ret != 0) return ret; priv[0] |= 0x0C; *privSz = sz; return 0; }
static int ltm_dh_compute_key(unsigned char *shared, const BIGNUM * pub, DH *dh) { mp_int s, priv_key, p, peer_pub; int ret; if (dh->pub_key == NULL || dh->g == NULL || dh->priv_key == NULL) return -1; mp_init_multi(&s, &priv_key, &p, &peer_pub, NULL); BN2mpz(&p, dh->p); BN2mpz(&peer_pub, pub); /* check if peers pubkey is reasonable */ if (mp_isneg(&peer_pub) || mp_cmp(&peer_pub, &p) >= 0 || mp_cmp_d(&peer_pub, 1) <= 0) { ret = -1; goto out; } BN2mpz(&priv_key, dh->priv_key); ret = mp_exptmod(&peer_pub, &priv_key, &p, &s); if (ret != 0) { ret = -1; goto out; } ret = mp_unsigned_bin_size(&s); mp_to_unsigned_bin(&s, shared); out: mp_clear_multi(&s, &priv_key, &p, &peer_pub, NULL); return ret; }