Ejemplo n.º 1
0
int
bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, int slen,
  uint8_t key_id)
{
    int rc;
    uint8_t *cp;
    uint8_t *end;
    mbedtls_ecdsa_context ctx;

    mbedtls_ecdsa_init(&ctx);

    cp = (uint8_t *)bootutil_keys[key_id].key;
    end = cp + *bootutil_keys[key_id].len;

    rc = bootutil_parse_eckey(&ctx, &cp, end);
    if (rc) {
        return -1;
    }

    while (sig[slen - 1] == '\0') {
        slen--;
    }
    rc = bootutil_cmp_sig(&ctx, hash, hlen, sig, slen);
    mbedtls_ecdsa_free(&ctx);

    return rc;
}
Ejemplo n.º 2
0
static void *ecdsa_alloc_wrap( void )
{
    void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) );

    if( ctx != NULL )
        mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx );

    return( ctx );
}
Ejemplo n.º 3
0
TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key)
{
	TEE_Result res = TEE_SUCCESS;
	int lmd_res = 0;
	mbedtls_ecdsa_context ecdsa;
	size_t key_size_bytes = 0;
	size_t key_size_bits = 0;

	memset(&ecdsa, 0, sizeof(ecdsa));

	res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits);
	if (res != TEE_SUCCESS)
		return res;

	mbedtls_ecdsa_init(&ecdsa);

	/* Generate the ECC key */
	lmd_res = mbedtls_ecdsa_genkey(&ecdsa, key->curve, mbd_rand, NULL);
	if (lmd_res != 0) {
		res = TEE_ERROR_BAD_PARAMETERS;
		FMSG("mbedtls_ecdsa_genkey failed.");
		goto exit;
	}
	ecc_clear_precomputed(&ecdsa.grp);

	/* check the size of the keys */
	if ((mbedtls_mpi_bitlen(&ecdsa.Q.X) > key_size_bits) ||
	    (mbedtls_mpi_bitlen(&ecdsa.Q.Y) > key_size_bits) ||
	    (mbedtls_mpi_bitlen(&ecdsa.d) > key_size_bits)) {
		res = TEE_ERROR_BAD_PARAMETERS;
		FMSG("Check the size of the keys failed.");
		goto exit;
	}

	/* check LMD is returning z==1 */
	if (mbedtls_mpi_bitlen(&ecdsa.Q.Z) != 1) {
		res = TEE_ERROR_BAD_PARAMETERS;
		FMSG("Check LMD failed.");
		goto exit;
	}

	/* Copy the key */
	crypto_bignum_copy(key->d, (void *)&ecdsa.d);
	crypto_bignum_copy(key->x, (void *)&ecdsa.Q.X);
	crypto_bignum_copy(key->y, (void *)&ecdsa.Q.Y);

	res = TEE_SUCCESS;
exit:
	mbedtls_ecdsa_free(&ecdsa);		/* Free the temporary key */
	return res;
}
Ejemplo n.º 4
0
static void *eckey_rs_alloc( void )
{
    eckey_restart_ctx *rs_ctx;

    void *ctx = mbedtls_calloc( 1, sizeof( eckey_restart_ctx ) );

    if( ctx != NULL )
    {
        rs_ctx = ctx;
        mbedtls_ecdsa_restart_init( &rs_ctx->ecdsa_rs );
        mbedtls_ecdsa_init( &rs_ctx->ecdsa_ctx );
    }

    return( ctx );
}
Ejemplo n.º 5
0
static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg,
                       const unsigned char *hash, size_t hash_len,
                       const unsigned char *sig, size_t sig_len )
{
    int ret;
    mbedtls_ecdsa_context ecdsa;

    mbedtls_ecdsa_init( &ecdsa );

    if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
        ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len );

    mbedtls_ecdsa_free( &ecdsa );

    return( ret );
}
Ejemplo n.º 6
0
static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg,
                   const unsigned char *hash, size_t hash_len,
                   unsigned char *sig, size_t *sig_len,
                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
{
    int ret;
    mbedtls_ecdsa_context ecdsa;

    mbedtls_ecdsa_init( &ecdsa );

    if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 )
        ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len,
                               f_rng, p_rng );

    mbedtls_ecdsa_free( &ecdsa );

    return( ret );
}
Ejemplo n.º 7
0
ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
        ssh_auth_callback auth_fn, void *auth_data)
{
    ssh_key key = NULL;
    mbedtls_pk_context *rsa = NULL;
    mbedtls_pk_context *ecdsa = NULL;
    ed25519_privkey *ed25519 = NULL;
    enum ssh_keytypes_e type;
    int valid;
    /* mbedtls pk_parse_key expects strlen to count the 0 byte */
    size_t b64len = strlen(b64_key) + 1;
    unsigned char tmp[MAX_PASSPHRASE_SIZE] = {0};

    type = pki_privatekey_type_from_string(b64_key);
    if (type == SSH_KEYTYPE_UNKNOWN) {
        SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key.");
        return NULL;
    }

    switch (type) {
        case SSH_KEYTYPE_RSA:
            rsa = malloc(sizeof(mbedtls_pk_context));
            if (rsa == NULL) {
                return NULL;
            }

            mbedtls_pk_init(rsa);

            if (passphrase == NULL) {
                if (auth_fn) {
                    valid = auth_fn("Passphrase for private key:", (char *) tmp,
                            MAX_PASSPHRASE_SIZE, 0, 0, auth_data);
                    if (valid < 0) {
                        return NULL;
                    }
                    /* TODO fix signedness and strlen */
                    valid = mbedtls_pk_parse_key(rsa,
                            (const unsigned char *) b64_key,
                            b64len, tmp,
                            strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
                } else {
                    valid = mbedtls_pk_parse_key(rsa,
                            (const unsigned char *) b64_key,
                            b64len, NULL,
                            0);
                }
            } else {
                valid = mbedtls_pk_parse_key(rsa,
                        (const unsigned char *) b64_key, b64len,
                        (const unsigned char *) passphrase,
                        strnlen(passphrase, MAX_PASSPHRASE_SIZE));
            }

            if (valid != 0) {
                char error_buf[100];
                mbedtls_strerror(valid, error_buf, 100);
                SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf);
                goto fail;
            }
            break;
        case SSH_KEYTYPE_ECDSA:
            ecdsa = malloc(sizeof(mbedtls_pk_context));
            if (ecdsa == NULL) {
                return NULL;
            }

            mbedtls_pk_init(ecdsa);

            if (passphrase == NULL) {
                if (auth_fn) {
                    valid = auth_fn("Passphrase for private key:", (char *) tmp,
                            MAX_PASSPHRASE_SIZE, 0, 0, auth_data);
                    if (valid < 0) {
                        return NULL;
                    }
                    valid = mbedtls_pk_parse_key(ecdsa,
                            (const unsigned char *) b64_key,
                            b64len, tmp,
                            strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
                } else {
                    valid = mbedtls_pk_parse_key(ecdsa,
                            (const unsigned char *) b64_key,
                            b64len, NULL,
                            0);
                }
            } else {
                valid = mbedtls_pk_parse_key(ecdsa,
                        (const unsigned char *) b64_key, b64len,
                        (const unsigned char *) passphrase,
                        strnlen(passphrase, MAX_PASSPHRASE_SIZE));
            }

            if (valid != 0) {
                char error_buf[100];
                mbedtls_strerror(valid, error_buf, 100);
                SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf);
                goto fail;
            }
            break;
        case SSH_KEYTYPE_ED25519:
            /* Cannot open ed25519 keys with libmbedcrypto */
        default:
            SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d",
                    type);
            return NULL;
    }

    key = ssh_key_new();
    if (key == NULL) {
        goto fail;
    }

    key->type = type;
    key->type_c = ssh_key_type_to_char(type);
    key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
    key->rsa = rsa;
    if (ecdsa != NULL) {
        mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*ecdsa);

        key->ecdsa = malloc(sizeof(mbedtls_ecdsa_context));
        if (key->ecdsa == NULL) {
            goto fail;
        }

        mbedtls_ecdsa_init(key->ecdsa);
        mbedtls_ecdsa_from_keypair(key->ecdsa, keypair);
        mbedtls_pk_free(ecdsa);
        SAFE_FREE(ecdsa);
    } else {
        key->ecdsa = NULL;
    }
    key->ed25519_privkey = ed25519;
    rsa = NULL;
    ecdsa = NULL;
    if (key->type == SSH_KEYTYPE_ECDSA) {
        key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
        key->type_c = pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
    }

    return key;
fail:
    ssh_key_free(key);
    if (rsa != NULL) {
        mbedtls_pk_free(rsa);
        SAFE_FREE(rsa);
    }
    if (ecdsa != NULL) {
        mbedtls_pk_free(ecdsa);
        SAFE_FREE(ecdsa);
    }
    return NULL;
}
Ejemplo n.º 8
0
TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key,
				     const uint8_t *msg, size_t msg_len,
				     const uint8_t *sig, size_t sig_len)
{
	TEE_Result res = TEE_SUCCESS;
	int lmd_res = 0;
	mbedtls_ecdsa_context ecdsa;
	size_t key_size_bytes, key_size_bits = 0;
	uint8_t one[1] = { 1 };
	mbedtls_mpi r;
	mbedtls_mpi s;

	memset(&ecdsa, 0, sizeof(ecdsa));
	memset(&r, 0, sizeof(r));
	memset(&s, 0, sizeof(s));

	if (algo == 0)
		return TEE_ERROR_BAD_PARAMETERS;

	mbedtls_mpi_init(&r);
	mbedtls_mpi_init(&s);

	mbedtls_ecdsa_init(&ecdsa);

	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve);
	if (lmd_res != 0) {
		res = TEE_ERROR_NOT_SUPPORTED;
		goto out;
	}

	ecdsa.Q.X = *(mbedtls_mpi *)key->x;
	ecdsa.Q.Y = *(mbedtls_mpi *)key->y;
	mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one));

	res = ecc_get_keysize(key->curve, algo,
			      &key_size_bytes, &key_size_bits);
	if (res != TEE_SUCCESS) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	/* check keysize vs sig_len */
	if ((key_size_bytes * 2) != sig_len) {
		res = TEE_ERROR_BAD_PARAMETERS;
		goto out;
	}

	mbedtls_mpi_read_binary(&r, sig, sig_len / 2);
	mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2);

	lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q,
				       &r, &s);
	if (lmd_res != 0) {
		FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res);
		res = get_tee_result(lmd_res);
	}
out:
	mbedtls_mpi_free(&r);
	mbedtls_mpi_free(&s);
	/* Reset mpi to skip freeing here, those mpis will be freed with key */
	mbedtls_mpi_init(&ecdsa.Q.X);
	mbedtls_mpi_init(&ecdsa.Q.Y);
	mbedtls_ecdsa_free(&ecdsa);
	return res;
}
Ejemplo n.º 9
0
TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key,
				   const uint8_t *msg, size_t msg_len,
				   uint8_t *sig, size_t *sig_len)
{
	TEE_Result res = TEE_SUCCESS;
	int lmd_res = 0;
	const mbedtls_pk_info_t *pk_info = NULL;
	mbedtls_ecdsa_context ecdsa;
	size_t key_size_bytes = 0;
	size_t key_size_bits = 0;
	mbedtls_mpi r;
	mbedtls_mpi s;

	memset(&ecdsa, 0, sizeof(ecdsa));
	memset(&r, 0, sizeof(r));
	memset(&s, 0, sizeof(s));

	if (algo == 0)
		return TEE_ERROR_BAD_PARAMETERS;

	mbedtls_mpi_init(&r);
	mbedtls_mpi_init(&s);

	mbedtls_ecdsa_init(&ecdsa);
	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve);
	if (lmd_res != 0) {
		res = TEE_ERROR_NOT_SUPPORTED;
		goto out;
	}

	ecdsa.d = *(mbedtls_mpi *)key->d;

	res = ecc_get_keysize(key->curve, algo, &key_size_bytes,
			      &key_size_bits);
	if (res != TEE_SUCCESS)
		goto out;

	pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
	if (pk_info == NULL) {
		res = TEE_ERROR_NOT_SUPPORTED;
		goto out;
	}

	lmd_res = mbedtls_ecdsa_sign(&ecdsa.grp, &r, &s, &ecdsa.d, msg,
				     msg_len, mbd_rand, NULL);
	if (lmd_res == 0) {
		*sig_len = 2 * key_size_bytes;
		memset(sig, 0, *sig_len);
		mbedtls_mpi_write_binary(&r, sig + *sig_len / 2 -
					 mbedtls_mpi_size(&r),
					 mbedtls_mpi_size(&r));

		mbedtls_mpi_write_binary(&s, sig + *sig_len -
					 mbedtls_mpi_size(&s),
					 mbedtls_mpi_size(&s));
		res = TEE_SUCCESS;
	} else {
		FMSG("mbedtls_ecdsa_sign failed, returned 0x%x\n", -lmd_res);
		res = TEE_ERROR_GENERIC;
	}
out:
	mbedtls_mpi_free(&r);
	mbedtls_mpi_free(&s);
	/* Reset mpi to skip freeing here, those mpis will be freed with key */
	mbedtls_mpi_init(&ecdsa.d);
	mbedtls_ecdsa_free(&ecdsa);
	return res;
}
Ejemplo n.º 10
0
void tt_ecdsa_init(IN tt_ecdsa_t *dsa)
{
    TT_ASSERT(dsa != NULL);

    mbedtls_ecdsa_init(&dsa->ctx);
}