Example #1
0
int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
                      const unsigned char *salt, int saltlen, int iter,
                      const EVP_MD *digest, int keylen, unsigned char *out)
{
    const char *empty = "";
    int rv = 1;
    EVP_KDF_CTX *kctx;

    /* Keep documented behaviour. */
    if (pass == NULL) {
        pass = empty;
        passlen = 0;
    } else if (passlen == -1) {
        passlen = strlen(pass);
    }
    if (salt == NULL && saltlen == 0)
        salt = (unsigned char *)empty;

    kctx = EVP_KDF_CTX_new_id(EVP_KDF_PBKDF2);
    if (kctx == NULL)
        return 0;
    if (EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_PASS, pass, (size_t)passlen) != 1
            || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_SALT,
                            salt, (size_t)saltlen) != 1
            || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_ITER, iter) != 1
            || EVP_KDF_ctrl(kctx, EVP_KDF_CTRL_SET_MD, digest) != 1
            || EVP_KDF_derive(kctx, out, keylen) != 1)
        rv = 0;

    EVP_KDF_CTX_free(kctx);

# ifdef OPENSSL_DEBUG_PKCS5V2
    fprintf(stderr, "Password:\n");
    h__dump(pass, passlen);
    fprintf(stderr, "Salt:\n");
    h__dump(salt, saltlen);
    fprintf(stderr, "Iteration count %d\n", iter);
    fprintf(stderr, "Key:\n");
    h__dump(out, keylen);
# endif
    return rv;
}
Example #2
0
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
                       int saltlen, int id, int iter, int n,
                       unsigned char *out, const EVP_MD *md_type)
{
    unsigned char *B = NULL, *D = NULL, *I = NULL, *p = NULL, *Ai = NULL;
    int Slen, Plen, Ilen, Ijlen;
    int i, j, u, v;
    int ret = 0;
    BIGNUM *Ij = NULL, *Bpl1 = NULL; /* These hold Ij and B + 1 */
    EVP_MD_CTX *ctx = NULL;
#ifdef  OPENSSL_DEBUG_KEYGEN
    unsigned char *tmpout = out;
    int tmpn = n;
#endif

    ctx = EVP_MD_CTX_new();
    if (ctx == NULL)
        goto err;

#ifdef  OPENSSL_DEBUG_KEYGEN
    fprintf(stderr, "KEYGEN DEBUG\n");
    fprintf(stderr, "ID %d, ITER %d\n", id, iter);
    fprintf(stderr, "Password (length %d):\n", passlen);
    h__dump(pass, passlen);
    fprintf(stderr, "Salt (length %d):\n", saltlen);
    h__dump(salt, saltlen);
#endif
    v = EVP_MD_block_size(md_type);
    u = EVP_MD_size(md_type);
    if (u < 0 || v <= 0)
        goto err;
    D = OPENSSL_malloc(v);
    Ai = OPENSSL_malloc(u);
    B = OPENSSL_malloc(v + 1);
    Slen = v * ((saltlen + v - 1) / v);
    if (passlen)
        Plen = v * ((passlen + v - 1) / v);
    else
        Plen = 0;
    Ilen = Slen + Plen;
    I = OPENSSL_malloc(Ilen);
    Ij = BN_new();
    Bpl1 = BN_new();
    if (D == NULL || Ai == NULL || B == NULL || I == NULL || Ij == NULL
            || Bpl1 == NULL)
        goto err;
    for (i = 0; i < v; i++)
        D[i] = id;
    p = I;
    for (i = 0; i < Slen; i++)
        *p++ = salt[i % saltlen];
    for (i = 0; i < Plen; i++)
        *p++ = pass[i % passlen];
    for (;;) {
        if (!EVP_DigestInit_ex(ctx, md_type, NULL)
            || !EVP_DigestUpdate(ctx, D, v)
            || !EVP_DigestUpdate(ctx, I, Ilen)
            || !EVP_DigestFinal_ex(ctx, Ai, NULL))
            goto err;
        for (j = 1; j < iter; j++) {
            if (!EVP_DigestInit_ex(ctx, md_type, NULL)
                || !EVP_DigestUpdate(ctx, Ai, u)
                || !EVP_DigestFinal_ex(ctx, Ai, NULL))
                goto err;
        }
        memcpy(out, Ai, min(n, u));
        if (u >= n) {
#ifdef OPENSSL_DEBUG_KEYGEN
            fprintf(stderr, "Output KEY (length %d)\n", tmpn);
            h__dump(tmpout, tmpn);
#endif
            ret = 1;
            goto end;
        }
        n -= u;
        out += u;
        for (j = 0; j < v; j++)
            B[j] = Ai[j % u];
        /* Work out B + 1 first then can use B as tmp space */
        if (!BN_bin2bn(B, v, Bpl1))
            goto err;
        if (!BN_add_word(Bpl1, 1))
            goto err;
        for (j = 0; j < Ilen; j += v) {
            if (!BN_bin2bn(I + j, v, Ij))
                goto err;
            if (!BN_add(Ij, Ij, Bpl1))
                goto err;
            if (!BN_bn2bin(Ij, B))
                goto err;
            Ijlen = BN_num_bytes(Ij);
            /* If more than 2^(v*8) - 1 cut off MSB */
            if (Ijlen > v) {
                if (!BN_bn2bin(Ij, B))
                    goto err;
                memcpy(I + j, B + 1, v);
#ifndef PKCS12_BROKEN_KEYGEN
                /* If less than v bytes pad with zeroes */
            } else if (Ijlen < v) {
                memset(I + j, 0, v - Ijlen);
                if (!BN_bn2bin(Ij, I + j + v - Ijlen))
                    goto err;
#endif
            } else if (!BN_bn2bin(Ij, I + j))
                goto err;
        }
    }

 err:
    PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE);

 end:
    OPENSSL_free(Ai);
    OPENSSL_free(B);
    OPENSSL_free(D);
    OPENSSL_free(I);
    BN_free(Ij);
    BN_free(Bpl1);
    EVP_MD_CTX_free(ctx);
    return ret;
}
int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
	     int saltlen, int id, int iter, int n, unsigned char *out,
	     const EVP_MD *md_type)
{
	unsigned char *B, *D, *I, *p, *Ai;
	int Slen, Plen, Ilen, Ijlen;
	int i, j, u, v;
	int ret = 0;
	BIGNUM *Ij, *Bpl1;	/* These hold Ij and B + 1 */
	EVP_MD_CTX ctx;
#ifdef  DEBUG_KEYGEN
	unsigned char *tmpout = out;
	int tmpn = n;
#endif

#if 0
	if (!pass) {
		PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_PASSED_NULL_PARAMETER);
		return 0;
	}
#endif

	EVP_MD_CTX_init(&ctx);
#ifdef  DEBUG_KEYGEN
	TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR, "KEYGEN DEBUG\n");
	TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR, "ID %d, ITER %d\n", id, iter);
	TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR, "Password (length %d):\n", passlen);
	h__dump(pass, passlen);
	TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR, "Salt (length %d):\n", saltlen);
	h__dump(salt, saltlen);
#endif
	v = EVP_MD_block_size (md_type);
	u = EVP_MD_size (md_type);
	if (u < 0)
	    return 0;
	D = (unsigned char*)OPENSSL_malloc (v);
	Ai = (unsigned char*)OPENSSL_malloc (u);
	B = (unsigned char*)OPENSSL_malloc (v + 1);
	Slen = v * ((saltlen+v-1)/v);
	if(passlen) Plen = v * ((passlen+v-1)/v);
	else Plen = 0;
	Ilen = Slen + Plen;
	I = (unsigned char*)OPENSSL_malloc (Ilen);
	Ij = BN_new();
	Bpl1 = BN_new();
	if (!D || !Ai || !B || !I || !Ij || !Bpl1)
		goto err;
	for (i = 0; i < v; i++) D[i] = id;
	p = I;
	for (i = 0; i < Slen; i++) *p++ = salt[i % saltlen];
	for (i = 0; i < Plen; i++) *p++ = pass[i % passlen];
	for (;;) {
		EVP_DigestInit_ex(&ctx, md_type, NULL);
		EVP_DigestUpdate(&ctx, D, v);
		EVP_DigestUpdate(&ctx, I, Ilen);
		EVP_DigestFinal_ex(&ctx, Ai, NULL);
		for (j = 1; j < iter; j++) {
			EVP_DigestInit_ex(&ctx, md_type, NULL);
			EVP_DigestUpdate(&ctx, Ai, u);
			EVP_DigestFinal_ex(&ctx, Ai, NULL);
		}
		TINYCLR_SSL_MEMCPY (out, Ai, min (n, u));
		if (u >= n) {
#ifdef DEBUG_KEYGEN
			TINYCLR_SSL_FPRINTF(OPENSSL_TYPE__FILE_STDERR, "Output KEY (length %d)\n", tmpn);
			h__dump(tmpout, tmpn);
#endif
			ret = 1;
			goto end;
		}
		n -= u;
		out += u;
		for (j = 0; j < v; j++) B[j] = Ai[j % u];
		/* Work out B + 1 first then can use B as tmp space */
		if (!BN_bin2bn (B, v, Bpl1)) goto err;
		if (!BN_add_word (Bpl1, 1)) goto err;
		for (j = 0; j < Ilen ; j+=v) {
			if (!BN_bin2bn (I + j, v, Ij)) goto err;
			if (!BN_add (Ij, Ij, Bpl1)) goto err;
			BN_bn2bin (Ij, B);
			Ijlen = BN_num_bytes (Ij);
			/* If more than 2^(v*8) - 1 cut off MSB */
			if (Ijlen > v) {
				BN_bn2bin (Ij, B);
				TINYCLR_SSL_MEMCPY (I + j, B + 1, v);
#ifndef PKCS12_BROKEN_KEYGEN
			/* If less than v bytes pad with zeroes */
			} else if (Ijlen < v) {
				TINYCLR_SSL_MEMSET(I + j, 0, v - Ijlen);
				BN_bn2bin(Ij, I + j + v - Ijlen); 
#endif
			} else BN_bn2bin (Ij, I + j);
		}
	}

err:
	PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI,ERR_R_MALLOC_FAILURE);

end:
	OPENSSL_free (Ai);
	OPENSSL_free (B);
	OPENSSL_free (D);
	OPENSSL_free (I);
	BN_free (Ij);
	BN_free (Bpl1);
	EVP_MD_CTX_cleanup(&ctx);
	return ret;
}