tt_result_t tt_ecdsa_load(IN tt_ecdsa_t *dsa, IN tt_pk_t *pk) { mbedtls_ecdsa_context *ctx; mbedtls_ecp_keypair *ec; int e; TT_ASSERT(dsa != NULL); TT_ASSERT(pk != NULL); if (tt_pk_get_type(pk) != TT_ECKEY) { TT_ERROR("pk is not ec key"); return TT_FAIL; } ctx = &dsa->ctx; ec = mbedtls_pk_ec(pk->ctx); e = mbedtls_ecdsa_from_keypair(ctx, ec); if (e != 0) { tt_crypto_error("fail to copy ec key"); mbedtls_ecdsa_free(ctx); return TT_FAIL; } return TT_SUCCESS; }
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 ); }
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 ); }
static int eckey_verify_rs_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, void *rs_ctx ) { int ret; eckey_restart_ctx *rs = rs_ctx; /* Should never happen */ if( rs == NULL ) return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); /* set up our own sub-context if needed (that is, on first run) */ if( rs->ecdsa_ctx.grp.pbits == 0 ) MBEDTLS_MPI_CHK( mbedtls_ecdsa_from_keypair( &rs->ecdsa_ctx, ctx ) ); MBEDTLS_MPI_CHK( ecdsa_verify_rs_wrap( &rs->ecdsa_ctx, md_alg, hash, hash_len, sig, sig_len, &rs->ecdsa_rs ) ); cleanup: return( ret ); }
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; }