Example #1
0
static int x25519_keygen(EC_KEY *eckey)
{
    unsigned char *key;
    if (x25519_init_private(eckey, NULL) == 0)
        return 0;
    key = eckey->custom_data;
    if (RAND_bytes(key, EC_X25519_KEYLEN) <= 0)
        return 0;
    key[0] &= 248;
    key[31] &= 127;
    key[31] |= 64;
    /*
     * Although the private key is kept as an array in eckey->custom_data
     * Set eckey->priv_key too so existing code which uses
     * EC_KEY_get0_private_key() still works.
     */
    if (eckey->priv_key == NULL)
        eckey->priv_key = BN_secure_new();
    if (eckey->priv_key == NULL)
        return 0;
    if (BN_lebin2bn(eckey->custom_data, EC_X25519_KEYLEN, eckey->priv_key) ==
        NULL)
        return 0;
    if (eckey->pub_key == NULL)
        eckey->pub_key = EC_POINT_new(eckey->group);
    if (eckey->pub_key == NULL)
        return 0;
    return x25519_keygenpub(eckey);
}
Example #2
0
static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
{
    *r = BN_lebin2bn(*in, nbyte, NULL);
    if (*r == NULL)
        return 0;
    *in += nbyte;
    return 1;
}
Example #3
0
static int x25519_oct2priv(EC_KEY *eckey, unsigned char *buf, size_t len)
{
    if (len != EC_X25519_KEYLEN)
        return 0;
    if (x25519_init_private(eckey, buf) == 0)
        return 0;
    /*
     * Although the private key is kept as an array in eckey->custom_data
     * Set eckey->priv_key too so existing code which uses
     * EC_KEY_get0_private_key() still works.
     */
    if (eckey->priv_key == NULL)
        eckey->priv_key = BN_secure_new();
    if (eckey->priv_key == NULL)
        return 0;
    if (BN_lebin2bn(buf, EC_X25519_KEYLEN, eckey->priv_key) == NULL)
        return 0;
    return 1;
}
Example #4
0
static int test_param_construct(void)
{
    static const char *int_names[] = {
        "int", "long", "int32", "int64"
    };
    static const char *uint_names[] = {
        "uint", "ulong", "uint32", "uint64", "size_t"
    };
    static const unsigned char bn_val[16] = {
        0xac, 0x75, 0x22, 0x7d, 0x81, 0x06, 0x7a, 0x23,
        0xa6, 0xed, 0x87, 0xc7, 0xab, 0xf4, 0x73, 0x22
    };
    OSSL_PARAM params[20];
    char buf[100], buf2[100], *bufp, *bufp2;
    unsigned char ubuf[100];
    void *vp, *vpn = NULL, *vp2;
    OSSL_PARAM *p;
    const OSSL_PARAM *cp;
    static const OSSL_PARAM pend = OSSL_PARAM_END;
    int i, n = 0, ret = 0;
    unsigned int u;
    long int l;
    unsigned long int ul;
    int32_t i32;
    uint32_t u32;
    int64_t i64;
    uint64_t u64;
    size_t j, k, s, sz;
    double d, d2;
    BIGNUM *bn = NULL, *bn2 = NULL;

    params[n++] = OSSL_PARAM_construct_int("int", &i, &sz);
    params[n++] = OSSL_PARAM_construct_uint("uint", &u, &sz);
    params[n++] = OSSL_PARAM_construct_long("long", &l, &sz);
    params[n++] = OSSL_PARAM_construct_ulong("ulong", &ul, &sz);
    params[n++] = OSSL_PARAM_construct_int32("int32", &i32, &sz);
    params[n++] = OSSL_PARAM_construct_int64("int64", &i64, &sz);
    params[n++] = OSSL_PARAM_construct_uint32("uint32", &u32, &sz);
    params[n++] = OSSL_PARAM_construct_uint64("uint64", &u64, &sz);
    params[n++] = OSSL_PARAM_construct_size_t("size_t", &s, &sz);
    params[n++] = OSSL_PARAM_construct_double("double", &d, &sz);
    params[n++] = OSSL_PARAM_construct_BN("bignum", ubuf, sizeof(ubuf), &sz);
    params[n++] = OSSL_PARAM_construct_utf8_string("utf8str", buf, sizeof(buf),
                                                   &sz);
    params[n++] = OSSL_PARAM_construct_octet_string("octstr", buf, sizeof(buf),
                                                    &sz);
    params[n++] = OSSL_PARAM_construct_utf8_ptr("utf8ptr", &bufp, &sz);
    params[n++] = OSSL_PARAM_construct_octet_ptr("octptr", &vp, &sz);
    params[n] = pend;

    /* Search failure */
    if (!TEST_ptr_null(OSSL_PARAM_locate(params, "fnord")))
        goto err;

    /* All signed integral types */
    for (j = 0; j < OSSL_NELEM(int_names); j++) {
        if (!TEST_ptr(cp = OSSL_PARAM_locate(params, int_names[j]))
            || !TEST_true(OSSL_PARAM_set_int32(cp, (int32_t)(3 + j)))
            || !TEST_true(OSSL_PARAM_get_int64(cp, &i64))
            || !TEST_size_t_eq(cp->data_size, sz)
            || !TEST_size_t_eq((size_t)i64, 3 + j)) {
            TEST_note("iteration %zu var %s", j + 1, int_names[j]);
            goto err;
        }
    }
    /* All unsigned integral types */
    for (j = 0; j < OSSL_NELEM(uint_names); j++) {
        if (!TEST_ptr(cp = OSSL_PARAM_locate(params, uint_names[j]))
            || !TEST_true(OSSL_PARAM_set_uint32(cp, (uint32_t)(3 + j)))
            || !TEST_true(OSSL_PARAM_get_uint64(cp, &u64))
            || !TEST_size_t_eq(cp->data_size, sz)
            || !TEST_size_t_eq((size_t)u64, 3 + j)) {
            TEST_note("iteration %zu var %s", j + 1, uint_names[j]);
            goto err;
        }
    }
    /* Real */
    if (!TEST_ptr(cp = OSSL_PARAM_locate(params, "double"))
        || !TEST_true(OSSL_PARAM_set_double(cp, 3.14))
        || !TEST_true(OSSL_PARAM_get_double(cp, &d2))
        || !TEST_size_t_eq(sz, sizeof(double))
        || !TEST_double_eq(d, d2))
        goto err;
    /* UTF8 string */
    bufp = NULL;
    if (!TEST_ptr(cp = OSSL_PARAM_locate(params, "utf8str"))
        || !TEST_true(OSSL_PARAM_set_utf8_string(cp, "abcdef"))
        || !TEST_size_t_eq(sz, sizeof("abcdef"))
        || !TEST_true(OSSL_PARAM_get_utf8_string(cp, &bufp, 0))
        || !TEST_str_eq(bufp, "abcdef"))
        goto err;
    OPENSSL_free(bufp);
    bufp = buf2;
    if (!TEST_true(OSSL_PARAM_get_utf8_string(cp, &bufp, sizeof(buf2)))
        || !TEST_str_eq(buf2, "abcdef"))
        goto err;
    /* UTF8 pointer */
    bufp = buf;
    sz = 0;
    if (!TEST_ptr(cp = OSSL_PARAM_locate(params, "utf8ptr"))
        || !TEST_true(OSSL_PARAM_set_utf8_ptr(cp, "tuvwxyz"))
        || !TEST_size_t_eq(sz, sizeof("tuvwxyz"))
        || !TEST_str_eq(bufp, "tuvwxyz")
        || !TEST_true(OSSL_PARAM_get_utf8_ptr(cp, (const char **)&bufp2))
        || !TEST_ptr_eq(bufp2, bufp))
        goto err;
    /* OCTET string */
    if (!TEST_ptr(p = locate(params, "octstr"))
        || !TEST_true(OSSL_PARAM_set_octet_string(p, "abcdefghi",
                                                  sizeof("abcdefghi")))
        || !TEST_size_t_eq(sz, sizeof("abcdefghi")))
        goto err;
    /* Match the return size to avoid trailing garbage bytes */
    p->data_size = *p->return_size;
    if (!TEST_true(OSSL_PARAM_get_octet_string(p, &vpn, 0, &s))
        || !TEST_size_t_eq(s, sizeof("abcdefghi"))
        || !TEST_mem_eq(vpn, sizeof("abcdefghi"),
                        "abcdefghi", sizeof("abcdefghi")))
        goto err;
    vp = buf2;
    if (!TEST_true(OSSL_PARAM_get_octet_string(p, &vp, sizeof(buf2), &s))
        || !TEST_size_t_eq(s, sizeof("abcdefghi"))
        || !TEST_mem_eq(vp, sizeof("abcdefghi"),
                        "abcdefghi", sizeof("abcdefghi")))
        goto err;
    /* OCTET pointer */
    vp = &l;
    sz = 0;
    if (!TEST_ptr(p = locate(params, "octptr"))
        || !TEST_true(OSSL_PARAM_set_octet_ptr(p, &ul, sizeof(ul)))
        || !TEST_size_t_eq(sz, sizeof(ul))
        || !TEST_ptr_eq(vp, &ul))
        goto err;
    /* Match the return size to avoid trailing garbage bytes */
    p->data_size = *p->return_size;
    if (!TEST_true(OSSL_PARAM_get_octet_ptr(p, (const void **)&vp2, &k))
        || !TEST_size_t_eq(k, sizeof(ul))
        || !TEST_ptr_eq(vp2, vp))
        goto err;
    /* BIGNUM */
    if (!TEST_ptr(p = locate(params, "bignum"))
        || !TEST_ptr(bn = BN_lebin2bn(bn_val, (int)sizeof(bn_val), NULL))
        || !TEST_true(OSSL_PARAM_set_BN(p, bn))
        || !TEST_size_t_eq(sz, sizeof(bn_val)))
        goto err;
    /* Match the return size to avoid trailing garbage bytes */
    p->data_size = *p->return_size;
    if(!TEST_true(OSSL_PARAM_get_BN(p, &bn2))
        || !TEST_BN_eq(bn, bn2))
        goto err;
    ret = 1;
err:
    OPENSSL_free(vpn);
    BN_free(bn);
    BN_free(bn2);
    return ret;
}
Example #5
0
sgx_status_t sgx_rsa3072_sign(const uint8_t * p_data,
	uint32_t data_size,
	const sgx_rsa3072_key_t * p_key,
	sgx_rsa3072_signature_t * p_signature)
{
	if ((p_data == NULL) || (data_size < 1) || (p_key == NULL) ||
		(p_signature == NULL))
	{
		return SGX_ERROR_INVALID_PARAMETER;
	}

	sgx_status_t retval = SGX_ERROR_UNEXPECTED;
	RSA *priv_rsa_key = NULL;
	EVP_PKEY* priv_pkey = NULL;
	BIGNUM *n = NULL;
	BIGNUM *d = NULL;
	BIGNUM *e = NULL;
	EVP_MD_CTX* ctx = NULL;
	const EVP_MD* sha256_md = NULL;
	size_t siglen = SGX_RSA3072_KEY_SIZE;
	int ret = 0;

	CLEAR_OPENSSL_ERROR_QUEUE;

	do {
		// converts the modulus value of rsa key, represented as positive integer in little-endian into a BIGNUM
		//
		n = BN_lebin2bn((const unsigned char *)p_key->mod, sizeof(p_key->mod), 0);
		if (n == NULL) {
			break;
		}

		// converts the private exp value of rsa key, represented as positive integer in little-endian into a BIGNUM
		//
		d = BN_lebin2bn((const unsigned char *)p_key->d, sizeof(p_key->d), 0);
		if (d == NULL) {
			break;
		}

		// converts the public exp value of rsa key, represented as positive integer in little-endian into a BIGNUM
		//
		e = BN_lebin2bn((const unsigned char *)p_key->e, sizeof(p_key->e), 0);
		if (e == NULL) {
			break;
		}

		// allocates and initializes an RSA key structure
		//
		priv_rsa_key = RSA_new();
		if (priv_rsa_key == NULL) {
			retval = SGX_ERROR_OUT_OF_MEMORY;
			break;
		}

		// sets the modulus, private exp and public exp values of the RSA key
		//
		if (RSA_set0_key(priv_rsa_key, n, e, d) != 1) {
			BN_clear_free(n);
			BN_clear_free(d);
			BN_clear_free(e);
			break;
		}

		// allocates an empty EVP_PKEY structure
		//
		priv_pkey = EVP_PKEY_new();
		if (priv_pkey == NULL) {
			retval = SGX_ERROR_OUT_OF_MEMORY;
			break;
		}

		// set the referenced key to pub_rsa_key, however these use the supplied key internally and so key will be freed when the parent pkey is freed
		//
		if (EVP_PKEY_assign_RSA(priv_pkey, priv_rsa_key) != 1) {
			RSA_free(priv_rsa_key);
			break;
		}

		// allocates, initializes and returns a digest context
		//
		ctx = EVP_MD_CTX_new();
		if (NULL == ctx) {
			retval = SGX_ERROR_OUT_OF_MEMORY;
			break;
		}

		// return EVP_MD structures for SHA256 digest algorithm */
		//
		sha256_md = EVP_sha256();
		if (sha256_md == NULL) {
			break;
		}

		// sets up signing context ctx to use digest type
		//
		if (EVP_DigestSignInit(ctx, NULL, sha256_md, NULL, priv_pkey) <= 0) {
			break;
		}

		// hashes data_size bytes of data at p_data into the signature context ctx
		//
		if (EVP_DigestSignUpdate(ctx, (const void *)p_data, data_size) <= 0) {
			break;
		}

		// signs the data in ctx places the signature in p_signature.
		//
		ret = EVP_DigestSignFinal(ctx, (unsigned char *)p_signature, &siglen);//fails
		if (ret <= 0) {
			break;
		}

		// validates the signature size
		//
		if (SGX_RSA3072_KEY_SIZE != siglen) {
			break;
		}

		retval = SGX_SUCCESS;
	} while (0);

	if (retval != SGX_SUCCESS) {
		GET_LAST_OPENSSL_ERROR;
	}

	if (ctx)
		EVP_MD_CTX_free(ctx);
	if (priv_pkey) {
		EVP_PKEY_free(priv_pkey);
		priv_rsa_key = NULL;
		n = NULL;
		d = NULL;
		e = NULL;
	}
	if (priv_rsa_key) {
		RSA_free(priv_rsa_key);
		n = NULL;
		d = NULL;
		e = NULL;
	}
	if (n)
		BN_clear_free(n);
	if (d)
		BN_clear_free(d);
	if (e)
		BN_clear_free(e);

	return retval;
}
Example #6
0
sgx_status_t sgx_rsa3072_verify(const uint8_t *p_data,
	uint32_t data_size,
	const sgx_rsa3072_public_key_t *p_public,
	const sgx_rsa3072_signature_t *p_signature,
	sgx_rsa_result_t *p_result)
{
	if ((p_data == NULL) || (data_size < 1) || (p_public == NULL) ||
		(p_signature == NULL) || (p_result == NULL))
	{
		return SGX_ERROR_INVALID_PARAMETER;
	}
	*p_result = SGX_RSA_INVALID_SIGNATURE;

	sgx_status_t retval = SGX_ERROR_UNEXPECTED;
	int verified = 0;
	RSA *pub_rsa_key = NULL;
	EVP_PKEY *pub_pkey = NULL;
	BIGNUM *n = NULL;
	BIGNUM *e = NULL;
	const EVP_MD* sha256_md = NULL;
	EVP_MD_CTX *ctx = NULL;

	CLEAR_OPENSSL_ERROR_QUEUE;

	do {
		// converts the modulus value of rsa key, represented as positive integer in little-endian into a BIGNUM
		//
		n = BN_lebin2bn((const unsigned char *)p_public->mod, sizeof(p_public->mod), 0);
		if (n == NULL) {
			break;
		}

		// converts the public exp value of rsa key, represented as positive integer in little-endian into a BIGNUM
		//
		e = BN_lebin2bn((const unsigned char *)p_public->exp, sizeof(p_public->exp), 0);
		if (e == NULL) {
			break;
		}

		// allocates and initializes an RSA key structure
		//
		pub_rsa_key = RSA_new();
		if (pub_rsa_key == NULL) {
			retval = SGX_ERROR_OUT_OF_MEMORY;
			break;
		}

		// sets the modulus and public exp values of the RSA key
		//
		if (RSA_set0_key(pub_rsa_key, n, e, NULL) != 1) {
			BN_clear_free(n);
			BN_clear_free(e);
			break;
		}

		// allocates an empty EVP_PKEY structure
		//
		pub_pkey = EVP_PKEY_new();
		if (pub_pkey == NULL) {
			retval = SGX_ERROR_OUT_OF_MEMORY;
			break;
		}

		// set the referenced key to pub_rsa_key, however these use the supplied key internally and so key will be freed when the parent pkey is freed
		//
		if (EVP_PKEY_assign_RSA(pub_pkey, pub_rsa_key) != 1) {
			RSA_free(pub_rsa_key);
			break;
		}

		// allocates, initializes and returns a digest context
		//
		ctx = EVP_MD_CTX_new();
		if (ctx == NULL) {
			retval = SGX_ERROR_OUT_OF_MEMORY;
			break;
		}

		// return EVP_MD structures for SHA256 digest algorithm */
		//
		sha256_md = EVP_sha256();
		if (sha256_md == NULL) {
			break;
		}

		// sets up verification context ctx to use digest type
		//
		if (EVP_DigestVerifyInit(ctx, NULL, sha256_md, NULL, pub_pkey) <= 0) {
			break;
		}

		// hashes data_size bytes of data at p_data into the verification context ctx.
		// this function can be called several times on the same ctx to hash additional data
		//
		if (EVP_DigestVerifyUpdate(ctx, (const void *)p_data, data_size) <= 0) {
			break;
		}

		// verifies the data in ctx against the signature in p_signature of length SGX_RSA3072_KEY_SIZE
		//
		verified = EVP_DigestVerifyFinal(ctx, (const unsigned char *)p_signature, SGX_RSA3072_KEY_SIZE);
		if (verified) {
			*p_result = SGX_RSA_VALID;
		}
		else if (verified != 0) {
			break;
		}

		retval = SGX_SUCCESS;
	} while (0);

	if (retval != SGX_SUCCESS) {
		GET_LAST_OPENSSL_ERROR;
	}

	if (ctx)
		EVP_MD_CTX_free(ctx);
	if (pub_pkey) {
		EVP_PKEY_free(pub_pkey);
		pub_rsa_key = NULL;
		n = NULL;
		e = NULL;
	}
	if (pub_rsa_key) {
		RSA_free(pub_rsa_key);
		n = NULL;
		e = NULL;
	}
	if (n)
		BN_clear_free(n);
	if (e)
		BN_clear_free(e);

	return retval;
}