Пример #1
0
/*
 * After the test case has been processed by the DUT, the results
 * need to be JSON formated to be included in the vector set results
 * file that will be uploaded to the server.  This routine handles
 * the JSON processing for a single test case.
 */
static ACVP_RESULT acvp_cmac_output_tc(ACVP_CTX *ctx, ACVP_CMAC_TC *stc, JSON_Object *tc_rsp) {
    ACVP_RESULT rv = ACVP_SUCCESS;
    char *tmp = NULL;

    tmp = calloc(ACVP_CMAC_MACLEN_MAX + 1, sizeof(char));
    if (!tmp) {
        ACVP_LOG_ERR("Unable to malloc in acvp_cmac_output_tc");
        return ACVP_MALLOC_FAIL;
    }

    if (stc->verify) {
        json_object_set_boolean(tc_rsp, "testPassed", stc->ver_disposition);
    } else {
        rv = acvp_bin_to_hexstr(stc->mac, stc->mac_len, tmp, ACVP_CMAC_MACLEN_MAX);
        if (rv != ACVP_SUCCESS) {
            ACVP_LOG_ERR("hex conversion failure (mac)");
            goto end;
        }
        json_object_set_string(tc_rsp, "mac", tmp);
    }

end:
    if (tmp) free(tmp);

    return rv;
}
Пример #2
0
/*
 * This is the internal send function that takes the URI as an extra
 * parameter. This removes repeated code without having to change the
 * API that the library uses to send registrations
 */
static ACVP_RESULT acvp_network_action(ACVP_CTX *ctx,
                                       ACVP_NET_ACTION action,
                                       char *url,
                                       char *data,
                                       int data_len) {
    ACVP_RESULT rv = ACVP_SUCCESS;
    ACVP_NET_ACTION generic_action = 0;
    int check_data = 0;
    int curl_code = 0;

    if (!ctx) {
        ACVP_LOG_ERR("Missing ctx");
        return ACVP_NO_CTX;
    }

    if (!url) {
        ACVP_LOG_ERR("URL required for transmission");
        return ACVP_MISSING_ARG;
    }

    switch (action) {
    case ACVP_NET_GET:
    case ACVP_NET_GET_VS:
    case ACVP_NET_GET_VS_RESULT:
    case ACVP_NET_GET_VS_SAMPLE:
        generic_action = ACVP_NET_GET;
        break;

    case ACVP_NET_POST:
    case ACVP_NET_POST_REG:
        check_data = 1;
        generic_action = ACVP_NET_POST;
        break;

    case ACVP_NET_POST_LOGIN:
        /* Clear jwt if logging in */
        if (ctx->jwt_token) free(ctx->jwt_token);
        ctx->jwt_token = NULL;
        check_data = 1;
        generic_action = ACVP_NET_POST_LOGIN;
        break;

    case ACVP_NET_POST_VS_RESP:
        generic_action = ACVP_NET_POST_VS_RESP;
        break;
    }

    if (check_data && (!data || !data_len)) {
        ACVP_LOG_ERR("POST action requires non-zero data/data_len");
        return ACVP_NO_DATA;
    }

    rv = execute_network_action(ctx, generic_action, url,
                                data, data_len, &curl_code);

    /* Log to the console */
    log_network_status(ctx, action, curl_code, url);

    return rv;
}
Пример #3
0
static ACVP_RESULT sanity_check_ctx(ACVP_CTX *ctx) {
    if (!ctx) {
        ACVP_LOG_ERR("Missing ctx");
        return ACVP_NO_CTX;
    }

    if (!ctx->server_port || !ctx->server_name) {
        ACVP_LOG_ERR("Call acvp_set_server to fill in server name and port");
        return ACVP_MISSING_ARG;
    }

    return ACVP_SUCCESS;
}
Пример #4
0
static struct curl_slist *acvp_add_auth_hdr(ACVP_CTX *ctx, struct curl_slist *slist) {
    char *bearer = NULL;
    char bearer_title[] = "Authorization: Bearer ";
    int bearer_title_size = (int)sizeof(bearer_title) - 1;
    int bearer_size = 0;

    if (!ctx->jwt_token && !(ctx->tmp_jwt && ctx->use_tmp_jwt)) {
        /*
         * We don't have a token to embed
         */
        return slist;
    }

    if (ctx->use_tmp_jwt && !ctx->tmp_jwt) {
        ACVP_LOG_ERR("Trying to use tmp_jwt, but it is NULL");
        return slist;
    }

    if (ctx->use_tmp_jwt) {
        bearer_size = strnlen_s(ctx->tmp_jwt, ACVP_JWT_TOKEN_MAX) + bearer_title_size;
    } else {
        bearer_size = strnlen_s(ctx->jwt_token, ACVP_JWT_TOKEN_MAX) + bearer_title_size;
    }

    bearer = calloc(bearer_size + 1, sizeof(char));
    if (!bearer) {
        ACVP_LOG_ERR("unable to allocate memory.");
        goto end;
    }

    if (ctx->use_tmp_jwt) {
        snprintf(bearer, bearer_size + 1, "%s%s", bearer_title, ctx->tmp_jwt);
    } else {
        snprintf(bearer, bearer_size + 1, "%s%s", bearer_title, ctx->jwt_token);
    }

    slist = curl_slist_append(slist, bearer);

    free(bearer);

end:
    if (ctx->use_tmp_jwt) {
        /* 
         * This was a single-use token.
         * Turn it off now... the library might turn it back on later.
         */
        ctx->use_tmp_jwt = 0;
    }

    return slist;
}
Пример #5
0
static ACVP_RESULT inspect_http_code(ACVP_CTX *ctx, int code) {
    ACVP_RESULT result = ACVP_TRANSPORT_FAIL; /* Generic failure */
    JSON_Value *root_value = NULL;
    const JSON_Object *obj = NULL;
    const char *err_str = NULL;

    if (code == HTTP_OK) {
        /* 200 */
        return ACVP_SUCCESS;
    }

    if (code == HTTP_UNAUTH) {
        int diff = 1;

        root_value = json_parse_string(ctx->curl_buf);

        obj = json_value_get_object(root_value);
        if (!obj) {
            ACVP_LOG_ERR("HTTP body doesn't contain top-level JSON object");
            goto end;
        }

        err_str = json_object_get_string(obj, "error");
        if (!err_str) {
            ACVP_LOG_ERR("JSON object doesn't contain 'error'");
            goto end;
        }

        strncmp_s(JWT_EXPIRED_STR, JWT_EXPIRED_STR_LEN, err_str, JWT_EXPIRED_STR_LEN, &diff);
        if (!diff) {
            result = ACVP_JWT_EXPIRED;
            goto end;
        }

        strncmp_s(JWT_INVALID_STR, JWT_INVALID_STR_LEN, err_str, JWT_INVALID_STR_LEN, &diff);
        if (!diff) {
            result = ACVP_JWT_INVALID;
            goto end;
        }
    }

end:
    if (root_value) json_value_free(root_value);

    return result;
}
Пример #6
0
/*
 * Forward prototypes for local functions
 */
static ACVP_RESULT acvp_kdf135_ikev1_output_tc(ACVP_CTX *ctx, ACVP_KDF135_IKEV1_TC *stc, JSON_Object *tc_rsp) {
    ACVP_RESULT rv;
    char *tmp = NULL;

    tmp = calloc(ACVP_KDF135_IKEV1_SKEY_STR_MAX + 1, sizeof(char));
    if (!tmp) {
        ACVP_LOG_ERR("Unable to malloc in acvp_kdf135 tpm_output_tc");
        return ACVP_MALLOC_FAIL;
    }

    rv = acvp_bin_to_hexstr(stc->s_key_id, stc->s_key_id_len, tmp, ACVP_KDF135_IKEV1_SKEY_STR_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (s_key_id)");
        goto err;
    }
    json_object_set_string(tc_rsp, "sKeyId", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_IKEV1_SKEY_STR_MAX);

    rv = acvp_bin_to_hexstr(stc->s_key_id_d, stc->s_key_id_d_len, tmp, ACVP_KDF135_IKEV1_SKEY_STR_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (s_key_id_d)");
        goto err;
    }
    json_object_set_string(tc_rsp, "sKeyIdD", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_IKEV1_SKEY_STR_MAX);

    rv = acvp_bin_to_hexstr(stc->s_key_id_a, stc->s_key_id_a_len, tmp, ACVP_KDF135_IKEV1_SKEY_STR_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (s_key_id_a)");
        goto err;
    }
    json_object_set_string(tc_rsp, "sKeyIdA", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_IKEV1_SKEY_STR_MAX);

    rv = acvp_bin_to_hexstr(stc->s_key_id_e, stc->s_key_id_e_len, tmp, ACVP_KDF135_IKEV1_SKEY_STR_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (s_key_id_e)");
        goto err;
    }
    json_object_set_string(tc_rsp, "sKeyIdE", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_IKEV1_SKEY_STR_MAX);

err:
    free(tmp);
    return rv;
}
Пример #7
0
/*
 * After the test case has been processed by the DUT, the results
 * need to be JSON formated to be included in the vector set results
 * file that will be uploaded to the server.  This routine handles
 * the JSON processing for a single test case.
 */
static ACVP_RESULT acvp_kdf135_srtp_output_tc(ACVP_CTX *ctx, ACVP_KDF135_SRTP_TC *stc, JSON_Object *tc_rsp) {
    ACVP_RESULT rv = ACVP_SUCCESS;
    char *tmp = NULL;

    tmp = calloc(ACVP_KDF135_SRTP_OUTPUT_MAX + 1, sizeof(char));
    if (!tmp) { return ACVP_MALLOC_FAIL; }

    rv = acvp_bin_to_hexstr(stc->srtp_ke, stc->aes_keylen / 8, tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (srtp_ke)");
        goto err;
    }
    json_object_set_string(tc_rsp, "srtpKe", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);

    rv = acvp_bin_to_hexstr(stc->srtp_ka, 160 / 8, tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (srtp_ka)");
        goto err;
    }
    json_object_set_string(tc_rsp, "srtpKa", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);

    rv = acvp_bin_to_hexstr(stc->srtp_ks, 112 / 8, tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (srtp_ks)");
        goto err;
    }
    json_object_set_string(tc_rsp, "srtpKs", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);

    rv = acvp_bin_to_hexstr(stc->srtcp_ke, stc->aes_keylen / 8, tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (srtcp_ke)");
        goto err;
    }
    json_object_set_string(tc_rsp, "srtcpKe", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);

    rv = acvp_bin_to_hexstr(stc->srtcp_ka, 160 / 8, tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (srtcp_ka)");
        goto err;
    }
    json_object_set_string(tc_rsp, "srtcpKa", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);

    rv = acvp_bin_to_hexstr(stc->srtcp_ks, 112 / 8, tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("hex conversion failure (srtcp_ks)");
        goto err;
    }
    json_object_set_string(tc_rsp, "srtcpKs", (const char *)tmp);
    memzero_s(tmp, ACVP_KDF135_SRTP_OUTPUT_MAX);

err:
    free(tmp);
    return rv;
}
Пример #8
0
/*
 * Test KAT handler API.
 * The ctx is NULL, expecting failure.
 */
Test(CMAC_API, null_ctx) {
    val = json_parse_file("json/cmac/cmac_aes.json");

    obj = ut_get_obj_from_rsp(val);
    if (!obj) {
        ACVP_LOG_ERR("JSON obj parse error");
        return;
    }

    /* Test with NULL JSON object */
    rv  = acvp_cmac_kat_handler(NULL, obj);
    cr_assert(rv == ACVP_NO_CTX);
    json_value_free(val);
}
Пример #9
0
ACVP_RESULT acvp_transport_get(ACVP_CTX *ctx, const char *url) {
    ACVP_RESULT rv = 0;
    char constructed_url[ACVP_ATTR_URL_MAX] = {0};

    rv = sanity_check_ctx(ctx);
    if (ACVP_SUCCESS != rv) return rv;

    if (!url) {
        ACVP_LOG_ERR("Missing url");
        return ACVP_MISSING_ARG;
    }

    snprintf(constructed_url, ACVP_ATTR_URL_MAX - 1,
             "https://%s:%d/%s",
             ctx->server_name, ctx->server_port, url);

    return acvp_network_action(ctx, ACVP_NET_GET, constructed_url, NULL, 0);
}
Пример #10
0
ACVP_RESULT acvp_retrieve_expected_result(ACVP_CTX *ctx, char *api_url) {
    ACVP_RESULT rv = 0;
    char url[ACVP_ATTR_URL_MAX] = {0};

    rv = sanity_check_ctx(ctx);
    if (ACVP_SUCCESS != rv) return rv;

    if (!api_url) {
        ACVP_LOG_ERR("Missing api_url");
        return ACVP_MISSING_ARG;
    }

    snprintf(url, ACVP_ATTR_URL_MAX - 1,
            "https://%s:%d/%s/expected",
            ctx->server_name, ctx->server_port, api_url);

    return acvp_network_action(ctx, ACVP_NET_GET_VS_SAMPLE, url, NULL, 0);
}
Пример #11
0
/*
 * This is the top level function used within libacvp to retrieve
 * a KAT vector set from the ACVP server.
 */
ACVP_RESULT acvp_retrieve_vector_set(ACVP_CTX *ctx, char *vsid_url) {
    ACVP_RESULT rv = 0;
    char url[ACVP_ATTR_URL_MAX] = {0};

    rv = sanity_check_ctx(ctx);
    if (ACVP_SUCCESS != rv) return rv;

    if (!vsid_url) {
        ACVP_LOG_ERR("Missing vsid_url");
        return ACVP_MISSING_ARG;
    }

    snprintf(url, ACVP_ATTR_URL_MAX - 1,
            "https://%s:%d/%s",
            ctx->server_name, ctx->server_port, vsid_url);

    return acvp_network_action(ctx, ACVP_NET_GET_VS, url, NULL, 0);
}
Пример #12
0
ACVP_RESULT acvp_send_test_session_registration(ACVP_CTX *ctx, char *reg, int len) {
    ACVP_RESULT rv = 0;
    char url[ACVP_ATTR_URL_MAX] = {0};

    rv = sanity_check_ctx(ctx);
    if (ACVP_SUCCESS != rv) return rv;

    if (!ctx->path_segment) {
        ACVP_LOG_ERR("No path segment, need to call acvp_set_path_segment first");
        return ACVP_MISSING_ARG;
    }

    snprintf(url, ACVP_ATTR_URL_MAX - 1,
             "https://%s:%d/%s%s", ctx->server_name,
             ctx->server_port, ctx->path_segment, ACVP_TEST_SESSIONS_URI);

    return acvp_network_action(ctx, ACVP_NET_POST_REG, url, reg, len);
}
Пример #13
0
/*
 * Test the KAT handler API.
 * The ctx is empty (no capabilities), expecting failure.
 */
Test(CMAC_API, empty_ctx) {
    setup_empty_ctx(&ctx);

    val = json_parse_file("json/cmac/cmac_aes.json");

    obj = ut_get_obj_from_rsp(val);
    if (!obj) {
        ACVP_LOG_ERR("JSON obj parse error");
        goto end;
    }

    rv  = acvp_cmac_kat_handler(ctx, obj);
    cr_assert(rv == ACVP_UNSUPPORTED_OP);
    json_value_free(val);

end:
    if (ctx) teardown_ctx(&ctx);
}
Пример #14
0
ACVP_RESULT acvp_transport_post(ACVP_CTX *ctx, const char *uri, char *data, int data_len) {
    ACVP_RESULT rv = 0;
    char constructed_url[ACVP_ATTR_URL_MAX] = {0};

    rv = sanity_check_ctx(ctx);
    if (ACVP_SUCCESS != rv) return rv;

    if (!uri) {
        ACVP_LOG_ERR("Missing uri");
        return ACVP_MISSING_ARG;
    }

    snprintf(constructed_url, ACVP_ATTR_URL_MAX - 1,
             "https://%s:%d/%s%s",
             ctx->server_name, ctx->server_port,
             ctx->path_segment, uri);

    return acvp_network_action(ctx, ACVP_NET_POST, constructed_url, data, data_len);
}
Пример #15
0
static ACVP_RESULT acvp_kdf135_ikev1_init_tc(ACVP_CTX *ctx,
                                             ACVP_KDF135_IKEV1_TC *stc,
                                             unsigned int tc_id,
                                             ACVP_HASH_ALG hash_alg,
                                             ACVP_KDF135_IKEV1_AUTH_METHOD auth_method,
                                             int init_nonce_len,
                                             int resp_nonce_len,
                                             int dh_secret_len,
                                             int psk_len,
                                             char *init_nonce,
                                             char *resp_nonce,
                                             char *init_ckey,
                                             char *resp_ckey,
                                             char *gxy,
                                             char *psk) {
    ACVP_RESULT rv = ACVP_SUCCESS;

    memzero_s(stc, sizeof(ACVP_KDF135_IKEV1_TC));

    stc->tc_id = tc_id;

    stc->hash_alg = hash_alg;
    stc->auth_method = auth_method;

    stc->init_nonce_len = ACVP_BIT2BYTE(init_nonce_len);
    stc->resp_nonce_len = ACVP_BIT2BYTE(resp_nonce_len);
    stc->dh_secret_len = ACVP_BIT2BYTE(dh_secret_len);
    stc->psk_len = ACVP_BIT2BYTE(psk_len);

    stc->init_nonce = calloc(ACVP_KDF135_IKEV1_INIT_NONCE_BYTE_MAX,
                             sizeof(unsigned char));
    if (!stc->init_nonce) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(init_nonce, stc->init_nonce, ACVP_KDF135_IKEV1_INIT_NONCE_BYTE_MAX, NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (init_nonce)");
        return rv;
    }

    stc->resp_nonce = calloc(ACVP_KDF135_IKEV1_RESP_NONCE_BYTE_MAX,
                             sizeof(unsigned char));
    if (!stc->resp_nonce) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(resp_nonce, stc->resp_nonce, ACVP_KDF135_IKEV1_RESP_NONCE_BYTE_MAX, NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (resp_nonce)");
        return rv;
    }

    stc->init_ckey = calloc(ACVP_KDF135_IKEV1_COOKIE_BYTE_MAX,
                            sizeof(unsigned char));
    if (!stc->init_ckey) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(init_ckey, stc->init_ckey, ACVP_KDF135_IKEV1_COOKIE_BYTE_MAX, NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (init_ckey)");
        return rv;
    }

    stc->resp_ckey = calloc(ACVP_KDF135_IKEV1_COOKIE_BYTE_MAX,
                            sizeof(unsigned char));
    if (!stc->resp_ckey) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(resp_ckey, stc->resp_ckey, ACVP_KDF135_IKEV1_COOKIE_BYTE_MAX, NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (resp_ckey)");
        return rv;
    }

    stc->gxy = calloc(ACVP_KDF135_IKEV1_DH_SHARED_SECRET_BYTE_MAX,
                      sizeof(unsigned char));
    if (!stc->gxy) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(gxy, stc->gxy, ACVP_KDF135_IKEV1_DH_SHARED_SECRET_BYTE_MAX, NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (gxy)");
        return rv;
    }

    if (psk != NULL) {
        /* Only for PSK authentication method */
        stc->psk = calloc(ACVP_KDF135_IKEV1_PSK_BYTE_MAX,
                          sizeof(unsigned char));
        if (!stc->psk) { return ACVP_MALLOC_FAIL; }
        rv = acvp_hexstr_to_bin(psk, stc->psk, ACVP_KDF135_IKEV1_PSK_BYTE_MAX, NULL);
        if (rv != ACVP_SUCCESS) {
            ACVP_LOG_ERR("Hex conversion failure (psk)");
            return rv;
        }
    }

    stc->s_key_id = calloc(ACVP_KDF135_IKEV1_SKEY_BYTE_MAX,
                           sizeof(unsigned char));
    if (!stc->s_key_id) { return ACVP_MALLOC_FAIL; }
    stc->s_key_id_a = calloc(ACVP_KDF135_IKEV1_SKEY_BYTE_MAX,
                             sizeof(unsigned char));
    if (!stc->s_key_id_a) { return ACVP_MALLOC_FAIL; }
    stc->s_key_id_d = calloc(ACVP_KDF135_IKEV1_SKEY_BYTE_MAX,
                             sizeof(unsigned char));
    if (!stc->s_key_id_d) { return ACVP_MALLOC_FAIL; }
    stc->s_key_id_e = calloc(ACVP_KDF135_IKEV1_SKEY_BYTE_MAX,
                             sizeof(unsigned char));
    if (!stc->s_key_id_e) { return ACVP_MALLOC_FAIL; }

    return rv;
}
Пример #16
0
static ACVP_RESULT execute_network_action(ACVP_CTX *ctx,
                                          ACVP_NET_ACTION action,
                                          char *url,
                                          char *data,
                                          int data_len,
                                          int *curl_code) {
    ACVP_RESULT result = 0;
    char *resp = NULL;
    char large_url[ACVP_ATTR_URL_MAX + 1] = {0};
    int large_submission = 0;
    int resp_len = 0;
    int rc = 0;

    switch(action) {
    case ACVP_NET_GET:
    case ACVP_NET_GET_VS:
    case ACVP_NET_GET_VS_RESULT:
    case ACVP_NET_GET_VS_SAMPLE:
        rc = acvp_curl_http_get(ctx, url);
        break;

    case ACVP_NET_POST:
    case ACVP_NET_POST_LOGIN:
    case ACVP_NET_POST_REG:
        rc = acvp_curl_http_post(ctx, url, data, data_len);
        break;

    case ACVP_NET_POST_VS_RESP:
        resp = json_serialize_to_string(ctx->kat_resp, &resp_len);
        if (!resp) {
            ACVP_LOG_ERR("Faled to serialize JSON to string");
            return ACVP_JSON_ERR;
        }
        json_value_free(ctx->kat_resp);
        ctx->kat_resp = NULL;

        if (ctx->post_size_constraint && resp_len > ctx->post_size_constraint) {
            /* Determine if this POST body goes over the "constraint" */
            large_submission = 1;
        }

        if (large_submission) {
            /*
             * Need to tell the server about this large submission.
             * The server will supply us with a one-time "large" URL;
             */
            result = acvp_notify_large(ctx, url, large_url, resp_len);
            if (result != ACVP_SUCCESS) goto end;

            rc = acvp_curl_http_post(ctx, large_url, resp, resp_len);
        } else {
            rc = acvp_curl_http_post(ctx, url, resp, resp_len);
        }

        break;

    default:
        ACVP_LOG_ERR("Unknown ACVP_NET_ACTION");
        return ACVP_INVALID_ARG;
    }

    /* Peek at the HTTP code */
    result = inspect_http_code(ctx, rc);

    if (result != ACVP_SUCCESS) {
        if (result == ACVP_JWT_EXPIRED &&
            action != ACVP_NET_POST_LOGIN) {
            /*
             * Expired JWT
             * We are going to refresh the session
             * and try to obtain a new JWT!
             * This should not ever happen during "login"...
             * and we need to avoid an infinite loop (via acvp_refesh).
             */
            ACVP_LOG_ERR("JWT authorization has timed out, curl rc=%d.\n"
                         "Refreshing session...", rc);

            result = acvp_refresh(ctx);
            if (result != ACVP_SUCCESS) {
                ACVP_LOG_ERR("JWT refresh failed.");
                goto end;
            }

            /* Try action again after the refresh */
            switch(action) {
            case ACVP_NET_GET:
            case ACVP_NET_GET_VS:
            case ACVP_NET_GET_VS_RESULT:
            case ACVP_NET_GET_VS_SAMPLE:
                rc = acvp_curl_http_get(ctx, url);
                break;

            case ACVP_NET_POST:
            case ACVP_NET_POST_REG:
                rc = acvp_curl_http_post(ctx, url, data, data_len);
                break;

            case ACVP_NET_POST_VS_RESP:
                if (large_submission) {
                    rc = acvp_curl_http_post(ctx, large_url, resp, resp_len);
                } else {
                    rc = acvp_curl_http_post(ctx, url, resp, resp_len);
                }
                break;

            case ACVP_NET_POST_LOGIN:
                ACVP_LOG_ERR("We should never be here!");
                break;
            }

            result = inspect_http_code(ctx, rc);
            if (result != ACVP_SUCCESS) {
                ACVP_LOG_ERR("Refreshed + retried, HTTP transport fails. curl rc=%d\n", rc);
                goto end;
            }
        } else if (result == ACVP_JWT_INVALID) {
            /*
             * Invalid JWT
             */
            ACVP_LOG_ERR("JWT invalid. curl rc=%d.\n", rc);
            goto end;
        }

        /* Generic error */
        goto end;
    }

    result = ACVP_SUCCESS;

end:
    if (resp) json_free_serialized_string(resp);

    *curl_code = rc;

    return result;
}
Пример #17
0
ACVP_RESULT acvp_kdf135_ikev1_kat_handler(ACVP_CTX *ctx, JSON_Object *obj) {
    unsigned int tc_id;
    JSON_Value *groupval;
    JSON_Object *groupobj = NULL;
    JSON_Value *testval;
    JSON_Object *testobj = NULL;
    JSON_Array *groups;
    JSON_Array *tests;

    JSON_Value *reg_arry_val = NULL;
    JSON_Object *reg_obj = NULL;
    JSON_Array *reg_arry = NULL;

    int i, g_cnt;
    int j, t_cnt;

    JSON_Value *r_vs_val = NULL;
    JSON_Object *r_vs = NULL;
    JSON_Array *r_tarr = NULL, *r_garr = NULL;  /* Response testarray, grouparray */
    JSON_Value *r_tval = NULL, *r_gval = NULL;  /* Response testval, groupval */
    JSON_Object *r_tobj = NULL, *r_gobj = NULL; /* Response testobj, groupobj */
    ACVP_CAPS_LIST *cap;
    ACVP_KDF135_IKEV1_TC stc;
    ACVP_TEST_CASE tc;
    ACVP_RESULT rv;
    const char *alg_str = json_object_get_string(obj, "algorithm");
    const char *mode_str = NULL;
    ACVP_CIPHER alg_id;
    char *json_result;

    ACVP_HASH_ALG hash_alg = 0;
    ACVP_KDF135_IKEV1_AUTH_METHOD auth_method = 0;
    const char *hash_alg_str = NULL, *auth_method_str = NULL;
    char *init_ckey = NULL, *resp_ckey = NULL, *gxy = NULL, *psk = NULL, *init_nonce = NULL, *resp_nonce = NULL;
    int init_nonce_len = 0, resp_nonce_len = 0, dh_secret_len = 0, psk_len = 0;

    if (!ctx) {
        ACVP_LOG_ERR("No ctx for handler operation");
        return ACVP_NO_CTX;
    }

    if (!alg_str) {
        ACVP_LOG_ERR("unable to parse 'algorithm' from JSON.");
        return ACVP_MALFORMED_JSON;
    }

    mode_str = json_object_get_string(obj, "mode");
    if (!mode_str) {
        ACVP_LOG_ERR("unable to parse 'mode' from JSON.");
        return ACVP_MALFORMED_JSON;
    }

    alg_id = acvp_lookup_cipher_w_mode_index(alg_str, mode_str);
    if (alg_id != ACVP_KDF135_IKEV1) {
        ACVP_LOG_ERR("Server JSON invalid 'algorithm' or 'mode'");
        return ACVP_INVALID_ARG;
    }

    /*
     * Get a reference to the abstracted test case
     */
    tc.tc.kdf135_ikev1 = &stc;
    stc.cipher = alg_id;

    cap = acvp_locate_cap_entry(ctx, alg_id);
    if (!cap) {
        ACVP_LOG_ERR("ACVP server requesting unsupported capability %s : %d.", alg_str, alg_id);
        return ACVP_UNSUPPORTED_OP;
    }

    /*
     * Create ACVP array for response
     */
    rv = acvp_create_array(&reg_obj, &reg_arry_val, &reg_arry);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Failed to create JSON response struct. ");
        return rv;
    }

    /*
     * Start to build the JSON response
     */
    rv = acvp_setup_json_rsp_group(&ctx, &reg_arry_val, &r_vs_val, &r_vs, alg_str, &r_garr);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Failed to setup json response");
        return rv;
    }

    groups = json_object_get_array(obj, "testGroups");
    g_cnt = json_array_get_count(groups);
    for (i = 0; i < g_cnt; i++) {
        int tgId = 0;
        groupval = json_array_get_value(groups, i);
        groupobj = json_value_get_object(groupval);

        /*
         * Create a new group in the response with the tgid
         * and an array of tests
         */
        r_gval = json_value_init_object();
        r_gobj = json_value_get_object(r_gval);
        tgId = json_object_get_number(groupobj, "tgId");
        if (!tgId) {
            ACVP_LOG_ERR("Missing tgid from server JSON groub obj");
            rv = ACVP_MALFORMED_JSON;
            goto err;
        }
        json_object_set_number(r_gobj, "tgId", tgId);
        json_object_set_value(r_gobj, "tests", json_value_init_array());
        r_tarr = json_object_get_array(r_gobj, "tests");

        hash_alg_str = json_object_get_string(groupobj, "hashAlg");
        if (!hash_alg_str) {
            ACVP_LOG_ERR("Failed to include hashAlg");
            rv = ACVP_MISSING_ARG;
            goto err;
        }
        hash_alg = acvp_lookup_hash_alg(hash_alg_str);
        if (hash_alg != ACVP_SHA1 && hash_alg != ACVP_SHA224 &&
            hash_alg != ACVP_SHA256 && hash_alg != ACVP_SHA384 &&
            hash_alg != ACVP_SHA512) {
            ACVP_LOG_ERR("ACVP server requesting invalid hashAlg");
            rv = ACVP_INVALID_ARG;
            goto err;
        }

        auth_method_str = json_object_get_string(groupobj, "authenticationMethod");
        if (!auth_method_str) {
            ACVP_LOG_ERR("Failed to include authenticationMethod");
            rv = ACVP_MISSING_ARG;
            goto err;
        }
        auth_method = read_auth_method(auth_method_str);
        if (!auth_method) {
            ACVP_LOG_ERR("ACVP server requesting invalid authenticationMethod");
            rv = ACVP_INVALID_ARG;
            goto err;
        }

        init_nonce_len = json_object_get_number(groupobj, "nInitLength");
        if (!(init_nonce_len >= ACVP_KDF135_IKEV1_INIT_NONCE_BIT_MIN &&
              init_nonce_len <= ACVP_KDF135_IKEV1_INIT_NONCE_BIT_MAX)) {
            ACVP_LOG_ERR("nInitLength incorrect, %d", init_nonce_len);
            rv = ACVP_INVALID_ARG;
            goto err;
        }

        resp_nonce_len = json_object_get_number(groupobj, "nRespLength");
        if (!(resp_nonce_len >= ACVP_KDF135_IKEV1_RESP_NONCE_BIT_MIN &&
              resp_nonce_len <= ACVP_KDF135_IKEV1_RESP_NONCE_BIT_MAX)) {
            ACVP_LOG_ERR("nRespLength incorrect, %d", resp_nonce_len);
            rv = ACVP_INVALID_ARG;
            goto err;
        }

        dh_secret_len = json_object_get_number(groupobj, "dhLength");
        if (!(dh_secret_len >= ACVP_KDF135_IKEV1_DH_SHARED_SECRET_BIT_MIN &&
              dh_secret_len <= ACVP_KDF135_IKEV1_DH_SHARED_SECRET_BIT_MAX)) {
            ACVP_LOG_ERR("dhLength incorrect, %d", dh_secret_len);
            rv = ACVP_INVALID_ARG;
            goto err;
        }

        if (auth_method == ACVP_KDF135_IKEV1_AMETH_PSK) {
            /* Only for PSK authentication method */
            psk_len = json_object_get_number(groupobj, "preSharedKeyLength");
            if (!(psk_len >= ACVP_KDF135_IKEV1_PSK_BIT_MIN &&
                  psk_len <= ACVP_KDF135_IKEV1_PSK_BIT_MAX)) {
                ACVP_LOG_ERR("preSharedKeyLength incorrect, %d", psk_len);
                rv = ACVP_INVALID_ARG;
                goto err;
            }
        }

        ACVP_LOG_INFO("\n    Test group: %d", i);
        ACVP_LOG_INFO("        hash alg: %s", hash_alg_str);
        ACVP_LOG_INFO("     auth method: %s", auth_method_str);
        ACVP_LOG_INFO("  init nonce len: %d", init_nonce_len);
        ACVP_LOG_INFO("  resp nonce len: %d", resp_nonce_len);
        ACVP_LOG_INFO("   dh secret len: %d", dh_secret_len);
        ACVP_LOG_INFO("         psk len: %d", psk_len);

        tests = json_object_get_array(groupobj, "tests");
        t_cnt = json_array_get_count(tests);

        for (j = 0; j < t_cnt; j++) {
            ACVP_LOG_INFO("Found new KDF IKEv1 test vector...");
            testval = json_array_get_value(tests, j);
            testobj = json_value_get_object(testval);

            tc_id = (unsigned int)json_object_get_number(testobj, "tcId");

            init_nonce = (char *)json_object_get_string(testobj, "nInit");
            if (!init_nonce) {
                ACVP_LOG_ERR("Failed to include nInit");
                rv = ACVP_MISSING_ARG;
                goto err;
            }
            if (strnlen_s((char *)init_nonce,
                        ACVP_KDF135_IKEV1_INIT_NONCE_STR_MAX + 1) != ((init_nonce_len + 7) / 8) * 2) {
                ACVP_LOG_ERR("nInit length(%d) incorrect, expected(%d)",
                             strnlen_s((char *)init_nonce,
                                     ACVP_KDF135_IKEV1_INIT_NONCE_STR_MAX + 1),
                             ((init_nonce_len + 7) / 8) * 2);
                rv = ACVP_INVALID_ARG;
                goto err;
            }

            resp_nonce = (char *)json_object_get_string(testobj, "nResp");
            if (!resp_nonce) {
                ACVP_LOG_ERR("Failed to include nResp");
                rv = ACVP_MISSING_ARG;
                goto err;
            }
            if (strnlen_s((char *)resp_nonce,
                        ACVP_KDF135_IKEV1_RESP_NONCE_STR_MAX + 1) != ((resp_nonce_len + 7) / 8) * 2) {
                ACVP_LOG_ERR("nResp length(%d) incorrect, expected(%d)",
                             strnlen_s((char *)resp_nonce,
                                     ACVP_KDF135_IKEV1_RESP_NONCE_STR_MAX + 1),
                             ((resp_nonce_len + 7) / 8) * 2);
                rv = ACVP_INVALID_ARG;
                goto err;
            }

            init_ckey = (char *)json_object_get_string(testobj, "ckyInit");
            if (!init_ckey) {
                ACVP_LOG_ERR("Failed to include ckyInit");
                rv = ACVP_MISSING_ARG;
                goto err;
            }
            if (strnlen_s((char *)init_ckey, ACVP_KDF135_IKEV1_COOKIE_STR_MAX + 1)
                > ACVP_KDF135_IKEV1_COOKIE_STR_MAX) {
                ACVP_LOG_ERR("ckyInit too long, max allowed=(%d)",
                             ACVP_KDF135_IKEV1_COOKIE_STR_MAX);
                rv = ACVP_INVALID_ARG;
                goto err;
            }

            resp_ckey = (char *)json_object_get_string(testobj, "ckyResp");
            if (!resp_ckey) {
                ACVP_LOG_ERR("Failed to include ckyResp");
                rv = ACVP_MISSING_ARG;
                goto err;
            }
            if (strnlen_s((char *)resp_ckey, ACVP_KDF135_IKEV1_COOKIE_STR_MAX + 1)
                > ACVP_KDF135_IKEV1_COOKIE_STR_MAX) {
                ACVP_LOG_ERR("ckyResp too long, max allowed=(%d)",
                             ACVP_KDF135_IKEV1_COOKIE_STR_MAX);
                rv = ACVP_INVALID_ARG;
                goto err;
            }

            gxy = (char *)json_object_get_string(testobj, "gxy");
            if (!gxy) {
                ACVP_LOG_ERR("Failed to include gxy");
                rv = ACVP_MISSING_ARG;
                goto err;
            }
            if (strnlen_s((char *)gxy, ACVP_KDF135_IKEV1_DH_SHARED_SECRET_STR_MAX + 1)
                > ACVP_KDF135_IKEV1_DH_SHARED_SECRET_STR_MAX) {
                ACVP_LOG_ERR("gxy too long, max allowed=(%d)",
                             ACVP_KDF135_IKEV1_DH_SHARED_SECRET_STR_MAX);
                rv = ACVP_INVALID_ARG;
                goto err;
            }


            if (auth_method == ACVP_KDF135_IKEV1_AMETH_PSK) {
                /* Only for PSK authentication method */
                psk = (char *)json_object_get_string(testobj, "preSharedKey");
                if (!psk) {
                    ACVP_LOG_ERR("Failed to include preSharedKey");
                    rv = ACVP_MISSING_ARG;
                    goto err;
                }
                if (strnlen_s((char *)psk, ACVP_KDF135_IKEV1_PSK_STR_MAX + 1)
                    > ACVP_KDF135_IKEV1_PSK_STR_MAX) {
                    ACVP_LOG_ERR("preSharedKey too long, max allowed=(%d)",
                                 ACVP_KDF135_IKEV1_PSK_STR_MAX);
                    rv = ACVP_INVALID_ARG;
                    goto err;
                }
            }

            ACVP_LOG_INFO("        Test case: %d", j);
            ACVP_LOG_INFO("             tcId: %d", tc_id);

            /*
             * Create a new test case in the response
             */
            r_tval = json_value_init_object();
            r_tobj = json_value_get_object(r_tval);

            json_object_set_number(r_tobj, "tcId", tc_id);

            /*
             * Setup the test case data that will be passed down to
             * the crypto module2
             */
            rv = acvp_kdf135_ikev1_init_tc(ctx, &stc, tc_id, hash_alg, auth_method,
                                           init_nonce_len, resp_nonce_len,
                                           dh_secret_len, psk_len,
                                           init_nonce, resp_nonce,
                                           init_ckey, resp_ckey,
                                           gxy, psk);
            if (rv != ACVP_SUCCESS) {
                acvp_kdf135_ikev1_release_tc(&stc);
                json_value_free(r_tval);
                goto err;
            }

            /* Process the current test vector... */
            if ((cap->crypto_handler)(&tc)) {
                ACVP_LOG_ERR("crypto module failed the KDF IKEv1 operation");
                acvp_kdf135_ikev1_release_tc(&stc);
                rv = ACVP_CRYPTO_MODULE_FAIL;
                json_value_free(r_tval);
                goto err;
            }

            /*
             * Output the test case results using JSON
             */
            rv = acvp_kdf135_ikev1_output_tc(ctx, &stc, r_tobj);
            if (rv != ACVP_SUCCESS) {
                ACVP_LOG_ERR("JSON output failure in hash module");
                acvp_kdf135_ikev1_release_tc(&stc);
                json_value_free(r_tval);
                goto err;
            }
            /*
             * Release all the memory associated with the test case
             */
            acvp_kdf135_ikev1_release_tc(&stc);

            /* Append the test response value to array */
            json_array_append_value(r_tarr, r_tval);
        }
        json_array_append_value(r_garr, r_gval);
    }

    json_array_append_value(reg_arry, r_vs_val);

    json_result = json_serialize_to_string_pretty(ctx->kat_resp, NULL);
    if (ctx->debug == ACVP_LOG_LVL_VERBOSE) {
        printf("\n\n%s\n\n", json_result);
    } else {
        ACVP_LOG_INFO("\n\n%s\n\n", json_result);
    }
    json_free_serialized_string(json_result);
    rv = ACVP_SUCCESS;

err:
    if (rv != ACVP_SUCCESS) {
        acvp_release_json(r_vs_val, r_gval);
    }
    return rv;
}
Пример #18
0
ACVP_RESULT acvp_kdf135_srtp_kat_handler(ACVP_CTX *ctx, JSON_Object *obj) {
    unsigned int tc_id;
    JSON_Value *groupval;
    JSON_Object *groupobj = NULL;
    JSON_Value *testval;
    JSON_Object *testobj = NULL;
    JSON_Array *groups;
    JSON_Array *tests;

    JSON_Value *reg_arry_val = NULL;
    JSON_Object *reg_obj = NULL;
    JSON_Array *reg_arry = NULL;

    int i, g_cnt;
    int j, t_cnt;

    JSON_Value *r_vs_val = NULL;
    JSON_Object *r_vs = NULL;
    JSON_Array *r_tarr = NULL, *r_garr = NULL;  /* Response testarray, grouparray */
    JSON_Value *r_tval = NULL, *r_gval = NULL;  /* Response testval, groupval */
    JSON_Object *r_tobj = NULL, *r_gobj = NULL; /* Response testobj, groupobj */
    ACVP_CAPS_LIST *cap;
    ACVP_KDF135_SRTP_TC stc;
    ACVP_TEST_CASE tc;
    ACVP_RESULT rv;
    const char *alg_str = json_object_get_string(obj, "algorithm");
    const char *mode_str = NULL;
    ACVP_CIPHER alg_id;
    char *json_result;

    int aes_key_length;
    char *kdr = NULL, *master_key = NULL, *master_salt = NULL, *index = NULL, *srtcp_index = NULL;

    if (!ctx) {
        ACVP_LOG_ERR("No ctx for handler operation");
        return ACVP_NO_CTX;
    }

    if (!alg_str) {
        ACVP_LOG_ERR("unable to parse 'algorithm' from JSON.");
        return ACVP_MALFORMED_JSON;
    }

    mode_str = json_object_get_string(obj, "mode");
    if (!mode_str) {
        ACVP_LOG_ERR("unable to parse 'mode' from JSON.");
        return ACVP_MALFORMED_JSON;
    }

    alg_id = acvp_lookup_cipher_w_mode_index(alg_str, mode_str);
    if (alg_id != ACVP_KDF135_SRTP) {
        ACVP_LOG_ERR("Server JSON invalid 'algorithm' or 'mode'");
        return ACVP_INVALID_ARG;
    }

    /*
     * Get a reference to the abstracted test case
     */
    tc.tc.kdf135_srtp = &stc;
    stc.cipher = alg_id;

    cap = acvp_locate_cap_entry(ctx, alg_id);
    if (!cap) {
        ACVP_LOG_ERR("ACVP server requesting unsupported capability %s : %d.", alg_str, alg_id);
        return ACVP_UNSUPPORTED_OP;
    }

    /*
     * Create ACVP array for response
     */
    rv = acvp_create_array(&reg_obj, &reg_arry_val, &reg_arry);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Failed to create JSON response struct. ");
        return rv;
    }

    /*
     * Start to build the JSON response
     */
    rv = acvp_setup_json_rsp_group(&ctx, &reg_arry_val, &r_vs_val, &r_vs, alg_str, &r_garr);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Failed to setup json response");
        goto err;
    }

    groups = json_object_get_array(obj, "testGroups");
    g_cnt = json_array_get_count(groups);
    for (i = 0; i < g_cnt; i++) {
        int tgId = 0;
        groupval = json_array_get_value(groups, i);
        groupobj = json_value_get_object(groupval);

        /*
         * Create a new group in the response with the tgid
         * and an array of tests
         */
        r_gval = json_value_init_object();
        r_gobj = json_value_get_object(r_gval);
        tgId = json_object_get_number(groupobj, "tgId");
        if (!tgId) {
            ACVP_LOG_ERR("Missing tgid from server JSON groub obj");
            rv = ACVP_MALFORMED_JSON;
            goto err;
        }
        json_object_set_number(r_gobj, "tgId", tgId);
        json_object_set_value(r_gobj, "tests", json_value_init_array());
        r_tarr = json_object_get_array(r_gobj, "tests");

        aes_key_length = (unsigned int)json_object_get_number(groupobj, "aesKeyLength");
        if (!aes_key_length) {
            ACVP_LOG_ERR("aesKeyLength incorrect, %d", aes_key_length);
            rv = ACVP_INVALID_ARG;
            goto err;
        }

        kdr = (char *)json_object_get_string(groupobj, "kdr");
        if (!kdr) {
            ACVP_LOG_ERR("Failed to include kdr");
            rv = ACVP_MISSING_ARG;
            goto err;
        }

        ACVP_LOG_INFO("\n    Test group: %d", i);
        ACVP_LOG_INFO("           kdr: %s", kdr);
        ACVP_LOG_INFO("    key length: %d", aes_key_length);

        tests = json_object_get_array(groupobj, "tests");
        t_cnt = json_array_get_count(tests);

        for (j = 0; j < t_cnt; j++) {
            ACVP_LOG_INFO("Found new KDF SRTP test vector...");
            testval = json_array_get_value(tests, j);
            testobj = json_value_get_object(testval);

            tc_id = (unsigned int)json_object_get_number(testobj, "tcId");

            master_key = (char *)json_object_get_string(testobj, "masterKey");
            if (!master_key) {
                ACVP_LOG_ERR("Failed to include JSON key:\"masterKey\"");
                rv = ACVP_MISSING_ARG;
                goto err;
            }

            master_salt = (char *)json_object_get_string(testobj, "masterSalt");
            if (!master_salt) {
                ACVP_LOG_ERR("Failed to include JSON key:\"masterSalt\"");
                rv = ACVP_MISSING_ARG;
                goto err;
            }

            index = (char *)json_object_get_string(testobj, "index");
            if (!index) {
                ACVP_LOG_ERR("Failed to include JSON key:\"index\"");
                rv = ACVP_MISSING_ARG;
                goto err;
            }

            srtcp_index = (char *)json_object_get_string(testobj, "srtcpIndex");
            if (!srtcp_index) {
                ACVP_LOG_ERR("Failed to include JSON key:\"srtcpIndex\"");
                rv = ACVP_MISSING_ARG;
                goto err;
            }

            ACVP_LOG_INFO("        Test case: %d", j);
            ACVP_LOG_INFO("             tcId: %d", tc_id);
            ACVP_LOG_INFO("        masterKey: %s", master_key);
            ACVP_LOG_INFO("       masterSalt: %s", master_salt);
            ACVP_LOG_INFO("            index: %s", index);
            ACVP_LOG_INFO("       srtcpIndex: %s", srtcp_index);

            /*
             * Create a new test case in the response
             */
            r_tval = json_value_init_object();
            r_tobj = json_value_get_object(r_tval);

            json_object_set_number(r_tobj, "tcId", tc_id);

            /*
             * Setup the test case data that will be passed down to
             * the crypto module.
             */
            rv = acvp_kdf135_srtp_init_tc(ctx, &stc, tc_id, aes_key_length, kdr, master_key, master_salt, index, srtcp_index);
            if (rv != ACVP_SUCCESS) {
                acvp_kdf135_srtp_release_tc(&stc);
                json_value_free(r_tval);
                goto err;
            }

            /* Process the current test vector... */
            if ((cap->crypto_handler)(&tc)) {
                ACVP_LOG_ERR("crypto module failed");
                acvp_kdf135_srtp_release_tc(&stc);
                rv = ACVP_CRYPTO_MODULE_FAIL;
                json_value_free(r_tval);
                goto err;
            }

            /*
             * Output the test case results using JSON
             */
            rv = acvp_kdf135_srtp_output_tc(ctx, &stc, r_tobj);
            if (rv != ACVP_SUCCESS) {
                ACVP_LOG_ERR("JSON output failure");
                acvp_kdf135_srtp_release_tc(&stc);
                json_value_free(r_tval);
                goto err;
            }
            /*
             * Release all the memory associated with the test case
             */
            acvp_kdf135_srtp_release_tc(&stc);

            /* Append the test response value to array */
            json_array_append_value(r_tarr, r_tval);
        }
        json_array_append_value(r_garr, r_gval);
    }

    json_array_append_value(reg_arry, r_vs_val);

    json_result = json_serialize_to_string_pretty(ctx->kat_resp, NULL);
    if (ctx->debug == ACVP_LOG_LVL_VERBOSE) {
        printf("\n\n%s\n\n", json_result);
    } else {
        ACVP_LOG_INFO("\n\n%s\n\n", json_result);
    }
    json_free_serialized_string(json_result);
    rv = ACVP_SUCCESS;

err:
    if (rv != ACVP_SUCCESS) {
        acvp_release_json(r_vs_val, r_gval);
    }
    return rv;
}
Пример #19
0
static ACVP_RESULT acvp_kdf135_srtp_init_tc(ACVP_CTX *ctx,
                                            ACVP_KDF135_SRTP_TC *stc,
                                            unsigned int tc_id,
                                            int aes_keylen,
                                            char *kdr,
                                            char *master_key,
                                            char *master_salt,
                                            char *index,
                                            char *srtcp_index) {
    ACVP_RESULT rv = ACVP_SUCCESS;

    memzero_s(stc, sizeof(ACVP_KDF135_SRTP_TC));

    if (!kdr || !master_key || !master_salt || !index || !srtcp_index) {
        ACVP_LOG_ERR("Missing parameters - initalize KDF SRTP test case");
        return ACVP_INVALID_ARG;
    }

    stc->tc_id = tc_id;
    stc->aes_keylen = aes_keylen;

    stc->kdr = calloc(ACVP_KDF135_SRTP_KDR_STR_MAX, sizeof(char));
    if (!stc->kdr) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(kdr, stc->kdr, ACVP_KDF135_SRTP_KDR_STR_MAX, &(stc->kdr_len));
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (kdr)");
        return rv;
    }

    stc->master_key = calloc(ACVP_KDF135_SRTP_MASTER_MAX, sizeof(char));
    if (!stc->master_key) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(master_key, (unsigned char *)stc->master_key,
                            ACVP_KDF135_SRTP_MASTER_MAX, NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (master_key)");
        return rv;
    }

    stc->master_salt = calloc(ACVP_KDF135_SRTP_MASTER_MAX, sizeof(char));
    if (!stc->master_salt) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(master_salt, (unsigned char *)stc->master_salt,
                            ACVP_KDF135_SRTP_MASTER_MAX, NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (master_salt)");
        return rv;
    }

    stc->index = calloc(ACVP_KDF135_SRTP_INDEX_MAX, sizeof(char));
    if (!stc->index) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(index, (unsigned char *)stc->index, ACVP_KDF135_SRTP_INDEX_MAX,
                            NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (index)");
        return rv;
    }

    stc->srtcp_index = calloc(ACVP_KDF135_SRTP_INDEX_MAX, sizeof(char));
    if (!stc->srtcp_index) { return ACVP_MALLOC_FAIL; }
    rv = acvp_hexstr_to_bin(srtcp_index, (unsigned char *)stc->srtcp_index,
                            ACVP_KDF135_SRTP_INDEX_MAX, NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex conversion failure (srtcp_index)");
        return rv;
    }

    stc->srtp_ka = calloc(ACVP_KDF135_SRTP_OUTPUT_MAX, sizeof(char));
    if (!stc->srtp_ka) { return ACVP_MALLOC_FAIL; }
    stc->srtp_ke = calloc(ACVP_KDF135_SRTP_OUTPUT_MAX, sizeof(char));
    if (!stc->srtp_ke) { return ACVP_MALLOC_FAIL; }
    stc->srtp_ks = calloc(ACVP_KDF135_SRTP_OUTPUT_MAX, sizeof(char));
    if (!stc->srtp_ks) { return ACVP_MALLOC_FAIL; }
    stc->srtcp_ka = calloc(ACVP_KDF135_SRTP_OUTPUT_MAX, sizeof(char));
    if (!stc->srtcp_ka) { return ACVP_MALLOC_FAIL; }
    stc->srtcp_ke = calloc(ACVP_KDF135_SRTP_OUTPUT_MAX, sizeof(char));
    if (!stc->srtcp_ke) { return ACVP_MALLOC_FAIL; }
    stc->srtcp_ks = calloc(ACVP_KDF135_SRTP_OUTPUT_MAX, sizeof(char));
    if (!stc->srtcp_ks) { return ACVP_MALLOC_FAIL; }

    return ACVP_SUCCESS;
}
Пример #20
0
static ACVP_RESULT acvp_cmac_init_tc(ACVP_CTX *ctx,
                                     ACVP_CMAC_TC *stc,
                                     unsigned int tc_id,
                                     char *msg,
                                     unsigned int msg_len,
                                     unsigned int key_len,
                                     char *key,
                                     char *key2,
                                     char *key3,
                                     int direction_verify,
                                     char *mac,
                                     unsigned int mac_len,
                                     ACVP_CIPHER alg_id) {
    ACVP_RESULT rv;

    if (!ctx) {
        return ACVP_NO_CTX;
    }
    if (alg_id != ACVP_CMAC_TDES && alg_id != ACVP_CMAC_AES) {
        return ACVP_INVALID_ARG;
    }
    if (!msg || !stc || !tc_id || !key) {
        return ACVP_INVALID_ARG;
    }
    if (alg_id == ACVP_CMAC_TDES && (!key2 || !key3)) {
        return ACVP_INVALID_ARG;
    }
    if (direction_verify) {
        if (!mac_len || !mac) {
            return ACVP_INVALID_ARG;
        }
    }

    memzero_s(stc, sizeof(ACVP_CMAC_TC));

    stc->msg = calloc(1, ACVP_CMAC_MSGLEN_MAX_STR);
    if (!stc->msg) { return ACVP_MALLOC_FAIL; }

    stc->mac = calloc(ACVP_CMAC_MACLEN_MAX, sizeof(char));
    if (!stc->mac) { return ACVP_MALLOC_FAIL; }
    stc->key = calloc(1, ACVP_CMAC_KEY_MAX);
    if (!stc->key) { return ACVP_MALLOC_FAIL; }
    stc->mac_len = mac_len;

    if (direction_verify) {
        rv = acvp_hexstr_to_bin(mac, stc->mac, ACVP_CMAC_MACLEN_MAX, (int *)&(stc->mac_len));
        if (rv != ACVP_SUCCESS) {
            ACVP_LOG_ERR("Hex converstion failure (mac)");
            return rv;
        }
    }

    stc->key2 = calloc(1, ACVP_CMAC_KEY_MAX);
    if (!stc->key2) { return ACVP_MALLOC_FAIL; }
    stc->key3 = calloc(1, ACVP_CMAC_KEY_MAX);
    if (!stc->key3) { return ACVP_MALLOC_FAIL; }

    rv = acvp_hexstr_to_bin(msg, stc->msg, ACVP_CMAC_MSGLEN_MAX_STR, NULL);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Hex converstion failure (msg)");
        return rv;
    }

    if (alg_id == ACVP_CMAC_AES) {
        rv = acvp_hexstr_to_bin(key, stc->key, ACVP_CMAC_KEY_MAX, (int *)&(stc->key_len));
        if (rv != ACVP_SUCCESS) {
            ACVP_LOG_ERR("Hex converstion failure (key)");
            return rv;
        }
    } else if (alg_id == ACVP_CMAC_TDES) {
        rv = acvp_hexstr_to_bin(key, stc->key, ACVP_CMAC_KEY_MAX, NULL);
        if (rv != ACVP_SUCCESS) {
            ACVP_LOG_ERR("Hex converstion failure (key1)");
            return rv;
        }
        rv = acvp_hexstr_to_bin(key2, stc->key2, ACVP_CMAC_KEY_MAX, NULL);
        if (rv != ACVP_SUCCESS) {
            ACVP_LOG_ERR("Hex converstion failure (key2)");
            return rv;
        }
        rv = acvp_hexstr_to_bin(key3, stc->key3, ACVP_CMAC_KEY_MAX, NULL);
        if (rv != ACVP_SUCCESS) {
            ACVP_LOG_ERR("Hex converstion failure (key3)");
            return rv;
        }
    }

    if (direction_verify) {
        stc->verify = 1;
    }

    stc->tc_id = tc_id;
    stc->msg_len = msg_len;
    stc->cipher = alg_id;

    return ACVP_SUCCESS;
}
Пример #21
0
ACVP_RESULT acvp_cmac_kat_handler(ACVP_CTX *ctx, JSON_Object *obj) {
    unsigned int tc_id, msglen, keyLen = 0, keyingOption = 0, maclen, verify = 0;
    char *msg = NULL, *key1 = NULL, *key2 = NULL, *key3 = NULL, *mac = NULL;
    JSON_Value *groupval;
    JSON_Object *groupobj = NULL;
    JSON_Value *testval;
    JSON_Object *testobj = NULL;
    JSON_Array *groups;
    JSON_Array *tests;

    JSON_Value *reg_arry_val = NULL;
    JSON_Object *reg_obj = NULL;
    JSON_Array *reg_arry = NULL;

    int i, g_cnt;
    int j, t_cnt;

    JSON_Value *r_vs_val = NULL;
    JSON_Object *r_vs = NULL;
    JSON_Array *r_tarr = NULL, *r_garr = NULL;  /* Response testarray, grouparray */
    JSON_Value *r_tval = NULL, *r_gval = NULL;  /* Response testval, groupval */
    JSON_Object *r_tobj = NULL, *r_gobj = NULL; /* Response testobj, groupobj */
    ACVP_CAPS_LIST *cap;
    ACVP_CMAC_TC stc;
    ACVP_TEST_CASE tc;
    ACVP_RESULT rv;
    const char *alg_str = json_object_get_string(obj, "algorithm");
    ACVP_CIPHER alg_id;
    char *json_result, *direction = NULL;
    int key1_len, key2_len, key3_len, json_msglen;

    if (!ctx) {
        ACVP_LOG_ERR("No ctx for handler operation");
        return ACVP_NO_CTX;
    }

    if (!obj) {
        ACVP_LOG_ERR("No obj for handler operation");
        return ACVP_MALFORMED_JSON;
    }

    if (!alg_str) {
        ACVP_LOG_ERR("ERROR: unable to parse 'algorithm' from JSON");
        return ACVP_MALFORMED_JSON;
    }

    /*
     * Get a reference to the abstracted test case
     */
    tc.tc.cmac = &stc;

    /*
     * Get the crypto module handler for this hash algorithm
     */
    alg_id = acvp_lookup_cipher_index(alg_str);
    if (alg_id < ACVP_CIPHER_START) {
        ACVP_LOG_ERR("ERROR: unsupported algorithm (%s)", alg_str);
        return ACVP_UNSUPPORTED_OP;
    }
    cap = acvp_locate_cap_entry(ctx, alg_id);
    if (!cap) {
        ACVP_LOG_ERR("ERROR: ACVP server requesting unsupported capability");
        return ACVP_UNSUPPORTED_OP;
    }

    /*
     * Create ACVP array for response
     */
    rv = acvp_create_array(&reg_obj, &reg_arry_val, &reg_arry);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("ERROR: Failed to create JSON response struct. ");
        return rv;
    }

    /*
     * Start to build the JSON response
     */
    rv = acvp_setup_json_rsp_group(&ctx, &reg_arry_val, &r_vs_val, &r_vs, alg_str, &r_garr);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Failed to setup json response");
        return rv;
    }

    groups = json_object_get_array(obj, "testGroups");
    g_cnt = json_array_get_count(groups);
    for (i = 0; i < g_cnt; i++) {
        int tgId = 0;
        int diff = 0;

        groupval = json_array_get_value(groups, i);
        groupobj = json_value_get_object(groupval);

        /*
         * Create a new group in the response with the tgid
         * and an array of tests
         */
        r_gval = json_value_init_object();
        r_gobj = json_value_get_object(r_gval);
        tgId = json_object_get_number(groupobj, "tgId");
        if (!tgId) {
            ACVP_LOG_ERR("Missing tgid from server JSON groub obj");
            rv = ACVP_MALFORMED_JSON;
            goto err;
        }
        json_object_set_number(r_gobj, "tgId", tgId);
        json_object_set_value(r_gobj, "tests", json_value_init_array());
        r_tarr = json_object_get_array(r_gobj, "tests");

        if (alg_id == ACVP_CMAC_AES) {
            keyLen = (unsigned int)json_object_get_number(groupobj, "keyLen");
            if (!keyLen) {
                ACVP_LOG_ERR("keylen missing from cmac aes json");
                rv = ACVP_MISSING_ARG;
                goto err;
            }
        } else if (alg_id == ACVP_CMAC_TDES) {
            keyingOption = (unsigned int)json_object_get_number(groupobj, "keyingOption");
            if (keyingOption <= ACVP_CMAC_TDES_KEYING_OPTION_MIN ||
                keyingOption >= ACVP_CMAC_TDES_KEYING_OPTION_MAX) {
                ACVP_LOG_ERR("keyingOption missing or wrong from cmac tdes json");
                rv = ACVP_INVALID_ARG;
                goto err;
            }
        }

        direction = (char *)json_object_get_string(groupobj, "direction");
        if (!direction) {
            ACVP_LOG_ERR("Unable to parse 'direction' from JSON.");
            rv = ACVP_MALFORMED_JSON;
            goto err;
        }

        strcmp_s("ver", 3, direction, &diff);
        if (!diff) {
            verify = 1;
        } else {
            strcmp_s("gen", 3, direction, &diff);
            if (diff) {
                ACVP_LOG_ERR("'direction' should be 'gen' or 'ver'");
                rv = ACVP_UNSUPPORTED_OP;
                goto err;
            }
        }

        msglen = (unsigned int)json_object_get_number(groupobj, "msgLen") / 8;

        maclen = (unsigned int)json_object_get_number(groupobj, "macLen") / 8;
        if (!maclen) {
            ACVP_LOG_ERR("Server JSON missing 'macLen'");
            rv = ACVP_MISSING_ARG;
            goto err;
        }

        ACVP_LOG_INFO("\n\n    Test group: %d", i);

        tests = json_object_get_array(groupobj, "tests");
        t_cnt = json_array_get_count(tests);
        for (j = 0; j < t_cnt; j++) {
            ACVP_LOG_INFO("Found new cmac test vector...");
            testval = json_array_get_value(tests, j);
            testobj = json_value_get_object(testval);

            tc_id = (unsigned int)json_object_get_number(testobj, "tcId");
            msg = (char *)json_object_get_string(testobj, "message");

            /* msg can be null if msglen is 0 */
            if (msg) {
                json_msglen = strnlen_s(msg, ACVP_CMAC_MSGLEN_MAX_STR + 1);
                if (json_msglen > ACVP_CMAC_MSGLEN_MAX_STR) {
                    ACVP_LOG_ERR("'msg' too long");
                    rv = ACVP_INVALID_ARG;
                    goto err;
                }
                if (!msglen && json_msglen > 0) {
                    ACVP_LOG_ERR("Server JSON missing 'msgLen'");
                    rv = ACVP_MISSING_ARG;
                    goto err;
                }
            } else if (msglen) {
                ACVP_LOG_ERR("msglen is nonzero, expected 'msg' in json");
                rv = ACVP_MISSING_ARG;
                goto err;
            }

            if (alg_id == ACVP_CMAC_AES) {
                key1 = (char *)json_object_get_string(testobj, "key");
                if (!key1) {
                    ACVP_LOG_ERR("Server JSON missing 'key'");
                    rv = ACVP_MISSING_ARG;
                    goto err;
                }
                key1_len = strnlen_s(key1, ACVP_CMAC_KEY_MAX + 1);
                if (key1_len > ACVP_CMAC_KEY_MAX) {
                    ACVP_LOG_ERR("Invalid length for 'key' attribute in CMAC-AES test");
                    rv = ACVP_INVALID_ARG;
                    goto err;
                }
            } else if (alg_id == ACVP_CMAC_TDES) {
                key1 = (char *)json_object_get_string(testobj, "key1");
                key2 = (char *)json_object_get_string(testobj, "key2");
                key3 = (char *)json_object_get_string(testobj, "key3");
                if (!key1 || !key2 || !key3) {
                    ACVP_LOG_ERR("Server JSON missing 'key(1,2,3)' value");
                    rv = ACVP_MISSING_ARG;
                    goto err;
                }
                key1_len = strnlen_s(key1, ACVP_CMAC_KEY_MAX + 1);
                key2_len = strnlen_s(key2, ACVP_CMAC_KEY_MAX + 1);
                key3_len = strnlen_s(key3, ACVP_CMAC_KEY_MAX + 1);
                if (key1_len > ACVP_CMAC_KEY_MAX ||
                    key2_len > ACVP_CMAC_KEY_MAX ||
                    key3_len > ACVP_CMAC_KEY_MAX) {
                    ACVP_LOG_ERR("Invalid length for 'key(1|2|3)' attribute in CMAC-TDES test");
                    rv = ACVP_INVALID_ARG;
                    goto err;
                }
            }

            if (verify) {
                mac = (char *)json_object_get_string(testobj, "mac");
                if (!mac) {
                    ACVP_LOG_ERR("Server JSON missing 'mac'");
                    rv = ACVP_MISSING_ARG;
                    goto err;
                }
            }

            ACVP_LOG_INFO("\n        Test case: %d", j);
            ACVP_LOG_INFO("             tcId: %d", tc_id);
            ACVP_LOG_INFO("        direction: %s", direction);

            ACVP_LOG_INFO("           msgLen: %d", msglen);
            ACVP_LOG_INFO("              msg: %s", msg);
            if (alg_id == ACVP_CMAC_AES) {
                ACVP_LOG_INFO("           keyLen: %d", keyLen);
                ACVP_LOG_INFO("              key: %s", key1);
            } else if (alg_id == ACVP_CMAC_TDES) {
                ACVP_LOG_INFO("     keyingOption: %d", keyingOption);
                ACVP_LOG_INFO("             key1: %s", key1);
                ACVP_LOG_INFO("             key2: %s", key2);
                ACVP_LOG_INFO("             key3: %s", key3);
            }

            if (verify) {
                ACVP_LOG_INFO("              mac: %s", mac);
            }

            /*
             * Create a new test case in the response
             */
            r_tval = json_value_init_object();
            r_tobj = json_value_get_object(r_tval);

            json_object_set_number(r_tobj, "tcId", tc_id);

            /*
             * Setup the test case data that will be passed down to
             * the crypto module.
             */
            rv = acvp_cmac_init_tc(ctx, &stc, tc_id, msg, msglen, keyLen, key1, key2, key3,
                                   verify, mac, maclen, alg_id);
            if (rv != ACVP_SUCCESS) {
                acvp_cmac_release_tc(&stc);
                json_value_free(r_tval);
                goto err;
            }

            /* Process the current test vector... */
            if ((cap->crypto_handler)(&tc)) {
                ACVP_LOG_ERR("ERROR: crypto module failed the operation");
                acvp_cmac_release_tc(&stc);
                rv = ACVP_CRYPTO_MODULE_FAIL;
                json_value_free(r_tval);
                goto err;
            }

            /*
             * Output the test case results using JSON
             */
            rv = acvp_cmac_output_tc(ctx, &stc, r_tobj);
            if (rv != ACVP_SUCCESS) {
                ACVP_LOG_ERR("ERROR: JSON output failure in hash module");
                acvp_cmac_release_tc(&stc);
                json_value_free(r_tval);
                goto err;
            }

            /*
             * Release all the memory associated with the test case
             */
            acvp_cmac_release_tc(&stc);

            /* Append the test response value to array */
            json_array_append_value(r_tarr, r_tval);
        }
        json_array_append_value(r_garr, r_gval);
    }

    json_array_append_value(reg_arry, r_vs_val);

    json_result = json_serialize_to_string_pretty(ctx->kat_resp, NULL);
    if (ctx->debug == ACVP_LOG_LVL_VERBOSE) {
        printf("\n\n%s\n\n", json_result);
    } else {
        ACVP_LOG_INFO("\n\n%s\n\n", json_result);
    }
    json_free_serialized_string(json_result);
    rv = ACVP_SUCCESS;

err:
    if (rv != ACVP_SUCCESS) {
        acvp_release_json(r_vs_val, r_gval);
    }
    return rv;
}
Пример #22
0
/*
 * After the test case has been processed by the DUT, the results
 * need to be JSON formated to be included in the vector set results
 * file that will be uploaded to the server.  This routine handles
 * the JSON processing for a single test case.
 */
static ACVP_RESULT acvp_kdf135_ssh_output_tc(ACVP_CTX *ctx,
                                             ACVP_KDF135_SSH_TC *stc,
                                             JSON_Object *tc_rsp) {
    char *tmp = NULL;
    ACVP_RESULT rv = ACVP_SUCCESS;

    if ((stc->iv_len * 2) > ACVP_KDF135_SSH_STR_OUT_MAX ||
        (stc->e_key_len * 2) > ACVP_KDF135_SSH_STR_OUT_MAX ||
        (stc->i_key_len * 2) > ACVP_KDF135_SSH_STR_OUT_MAX) {
        ACVP_LOG_ERR("iv_len*2(%u) || e_key_len*2(%u) || i_key_len*2(%u) > ACVP_KDF135_SSH_STR_OUT_MAX(%u)",
                     (stc->iv_len * 2), (stc->e_key_len * 2), (stc->i_key_len * 2),
                     ACVP_KDF135_SSH_STR_OUT_MAX);
        ACVP_LOG_ERR("Hint, make sure user isn't modifying those field values");
        return ACVP_DATA_TOO_LARGE;
    }

    tmp = calloc(ACVP_KDF135_SSH_STR_OUT_MAX + 1, sizeof(char));
    if (!tmp) {
        ACVP_LOG_ERR("Unable to malloc");
        return ACVP_MALLOC_FAIL;
    }

    rv = acvp_bin_to_hexstr(stc->cs_init_iv, stc->iv_len, tmp, ACVP_KDF135_SSH_STR_OUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("acvp_bin_to_hexstr() failure");
        goto err;
    }
    json_object_set_string(tc_rsp, "initialIvClient", tmp);
    memzero_s(tmp, ACVP_KDF135_SSH_STR_OUT_MAX);

    rv = acvp_bin_to_hexstr(stc->cs_encrypt_key, stc->e_key_len, tmp, ACVP_KDF135_SSH_STR_OUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("acvp_bin_to_hexstr() failure");
        goto err;
    }
    json_object_set_string(tc_rsp, "encryptionKeyClient", tmp);
    memzero_s(tmp, ACVP_KDF135_SSH_STR_OUT_MAX);

    rv = acvp_bin_to_hexstr(stc->cs_integrity_key, stc->i_key_len, tmp, ACVP_KDF135_SSH_STR_OUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("acvp_bin_to_hexstr() failure");
        goto err;
    }
    json_object_set_string(tc_rsp, "integrityKeyClient", tmp);
    memzero_s(tmp, ACVP_KDF135_SSH_STR_OUT_MAX);

    rv = acvp_bin_to_hexstr(stc->sc_init_iv, stc->iv_len, tmp, ACVP_KDF135_SSH_STR_OUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("acvp_bin_to_hexstr() failure");
        goto err;
    }
    json_object_set_string(tc_rsp, "initialIvServer", tmp);
    memzero_s(tmp, ACVP_KDF135_SSH_STR_OUT_MAX);

    rv = acvp_bin_to_hexstr(stc->sc_encrypt_key, stc->e_key_len, tmp, ACVP_KDF135_SSH_STR_OUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("acvp_bin_to_hexstr() failure");
        goto err;
    }
    json_object_set_string(tc_rsp, "encryptionKeyServer", tmp);
    memzero_s(tmp, ACVP_KDF135_SSH_STR_OUT_MAX);

    rv = acvp_bin_to_hexstr(stc->sc_integrity_key, stc->i_key_len, tmp, ACVP_KDF135_SSH_STR_OUT_MAX);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("acvp_bin_to_hexstr() failure");
        goto err;
    }
    json_object_set_string(tc_rsp, "integrityKeyServer", tmp);

err:
    free(tmp);
    return rv;
}
Пример #23
0
ACVP_RESULT acvp_kdf135_ssh_kat_handler(ACVP_CTX *ctx, JSON_Object *obj) {
    unsigned int tc_id;
    JSON_Value *groupval;
    JSON_Object *groupobj = NULL;
    JSON_Value *testval;
    JSON_Object *testobj = NULL;
    JSON_Array *groups;
    JSON_Array *tests;

    JSON_Value *reg_arry_val = NULL;
    JSON_Object *reg_obj = NULL;
    JSON_Array *reg_arry = NULL;

    int i, g_cnt;
    int j, t_cnt;

    JSON_Value *r_vs_val = NULL;
    JSON_Object *r_vs = NULL;
    JSON_Array *r_tarr = NULL, *r_garr = NULL;  /* Response testarray, grouparray */
    JSON_Value *r_tval = NULL, *r_gval = NULL;  /* Response testval, groupval */
    JSON_Object *r_tobj = NULL, *r_gobj = NULL; /* Response testobj, groupobj */
    ACVP_CAPS_LIST *cap;
    ACVP_KDF135_SSH_TC stc;
    ACVP_TEST_CASE tc;
    ACVP_RESULT rv;

    ACVP_CIPHER alg_id;
    const char *alg_str = NULL;
    const char *mode_str = NULL;
    const char *cipher_str = NULL;
    const char *shared_secret_str = NULL;
    const char *session_id_str = NULL;
    const char *hash_str = NULL;
    char *json_result;

    if (!ctx) {
        ACVP_LOG_ERR("No ctx for handler operation");
        return ACVP_NO_CTX;
    }

    if (!obj) {
        ACVP_LOG_ERR("No obj for handler operation");
        return ACVP_MALFORMED_JSON;
    }

    alg_str = json_object_get_string(obj, "algorithm");
    if (!alg_str) {
        ACVP_LOG_ERR("unable to parse 'algorithm' from JSON");
        return ACVP_MALFORMED_JSON;
    }

    mode_str = json_object_get_string(obj, "mode");
    if (!mode_str) {
        ACVP_LOG_ERR("unable to parse 'mode' from JSON");
        return ACVP_MALFORMED_JSON;
    }

    alg_id = acvp_lookup_cipher_w_mode_index(alg_str, mode_str);
    if (alg_id != ACVP_KDF135_SSH) {
        ACVP_LOG_ERR("Server JSON invalid 'algorithm' or 'mode'");
        return ACVP_INVALID_ARG;
    }

    /*
     * Get a reference to the abstracted test case
     */
    tc.tc.kdf135_ssh = &stc;

    /*
     * Get the crypto module handler for this hash algorithm
     */
    cap = acvp_locate_cap_entry(ctx, alg_id);
    if (!cap) {
        ACVP_LOG_ERR("ACVP server requesting unsupported capability %s : %d.", alg_str, alg_id);
        return ACVP_UNSUPPORTED_OP;
    }

    /*
     * Create ACVP array for response
     */
    rv = acvp_create_array(&reg_obj, &reg_arry_val, &reg_arry);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Failed to create JSON response struct. ");
        return rv;
    }

    /*
     * Start to build the JSON response
     */
    rv = acvp_setup_json_rsp_group(&ctx, &reg_arry_val, &r_vs_val, &r_vs, alg_str, &r_garr);
    if (rv != ACVP_SUCCESS) {
        ACVP_LOG_ERR("Failed to setup json response");
        return rv;
    }

    groups = json_object_get_array(obj, "testGroups");
    if (!groups) {
        ACVP_LOG_ERR("Failed to include testGroups. ");
        rv = ACVP_MISSING_ARG;
        goto err;
    }

    g_cnt = json_array_get_count(groups);
    for (i = 0; i < g_cnt; i++) {
        int tgId = 0;
        int diff = 1;
        unsigned int e_key_len = 0, i_key_len = 0,
                     hash_len = 0, iv_len = 0;
        ACVP_HASH_ALG sha_type = 0;
        const char *sha_str = NULL;
        groupval = json_array_get_value(groups, i);
        groupobj = json_value_get_object(groupval);

        /*
         * Create a new group in the response with the tgid
         * and an array of tests
         */
        r_gval = json_value_init_object();
        r_gobj = json_value_get_object(r_gval);
        tgId = json_object_get_number(groupobj, "tgId");
        if (!tgId) {
            ACVP_LOG_ERR("Missing tgid from server JSON groub obj");
            rv = ACVP_MALFORMED_JSON;
            goto err;
        }
        json_object_set_number(r_gobj, "tgId", tgId);
        json_object_set_value(r_gobj, "tests", json_value_init_array());
        r_tarr = json_object_get_array(r_gobj, "tests");

        // Get the expected (user will generate) key and iv lengths
        cipher_str = json_object_get_string(groupobj, "cipher");
        if (!cipher_str) {
            ACVP_LOG_ERR("Failed to include cipher. ");
            rv = ACVP_MISSING_ARG;
            goto err;
        }

        sha_str = json_object_get_string(groupobj, "hashAlg");
        if (!sha_str) {
            ACVP_LOG_ERR("Failed to include hashAlg. ");
            rv = ACVP_MISSING_ARG;
            goto err;
        }

        sha_type = acvp_lookup_hash_alg(sha_str);
        if (sha_type == ACVP_SHA1) {
            i_key_len = hash_len = ACVP_SHA1_BYTE_LEN;
        } else if (sha_type == ACVP_SHA224) {
            i_key_len = hash_len = ACVP_SHA224_BYTE_LEN;
        } else if (sha_type == ACVP_SHA256) {
            i_key_len = hash_len = ACVP_SHA256_BYTE_LEN;
        } else if (sha_type == ACVP_SHA384) {
            i_key_len = hash_len = ACVP_SHA384_BYTE_LEN;
        } else if (sha_type == ACVP_SHA512) {
            i_key_len = hash_len = ACVP_SHA512_BYTE_LEN;
        } else {
            ACVP_LOG_ERR("ACVP server requesting invalid hashAlg");
            rv = ACVP_NO_CAP;
            goto err;
        }

        /*
         * Determine the encrypt key_len, inferred from cipher.
         */
        strcmp_s(ACVP_MODE_TDES, 4, cipher_str, &diff);
        if (!diff) {
            e_key_len = ACVP_KEY_LEN_TDES;
            iv_len = ACVP_BLOCK_LEN_TDES;
        }

        strcmp_s(ACVP_MODE_AES_128, 7, cipher_str, &diff);
        if (!diff) {
            e_key_len = ACVP_KEY_LEN_AES128;
            iv_len = ACVP_BLOCK_LEN_AES128;
        }

        strcmp_s(ACVP_MODE_AES_192, 7, cipher_str, &diff);
        if (!diff) {
            e_key_len = ACVP_KEY_LEN_AES192;
            iv_len = ACVP_BLOCK_LEN_AES192;
        }

        strcmp_s(ACVP_MODE_AES_256, 7, cipher_str, &diff);
        if (!diff) {
            e_key_len = ACVP_KEY_LEN_AES256;
            iv_len = ACVP_BLOCK_LEN_AES256;
        }

        if (!e_key_len || !iv_len) {
            ACVP_LOG_ERR("Unsupported cipher type");
            rv = ACVP_NO_CAP;
            goto err;
        }


        /*
         * Log Test Group information...
         */
        ACVP_LOG_INFO("    Test group: %d", i);
        ACVP_LOG_INFO("        cipher: %s", cipher_str);
        ACVP_LOG_INFO("       hashAlg: %s", sha_str);

        tests = json_object_get_array(groupobj, "tests");
        if (!tests) {
            ACVP_LOG_ERR("Failed to include tests. ");
            rv = ACVP_MISSING_ARG;
            goto err;
        }

        t_cnt = json_array_get_count(tests);
        if (!t_cnt) {
            ACVP_LOG_ERR("Failed to include tests in array. ");
            rv = ACVP_MISSING_ARG;
            goto err;
        }

        for (j = 0; j < t_cnt; j++) {
            ACVP_LOG_INFO("Found new KDF SSH test vector...");
            testval = json_array_get_value(tests, j);
            testobj = json_value_get_object(testval);

            tc_id = (unsigned int)json_object_get_number(testobj, "tcId");
            if (!tc_id) {
                ACVP_LOG_ERR("Failed to include tc_id. ");
                rv = ACVP_MISSING_ARG;
                goto err;
            }

            shared_secret_str = json_object_get_string(testobj, "k");
            if (!shared_secret_str) {
                ACVP_LOG_ERR("Failed to include k. ");
                rv = ACVP_MISSING_ARG;
                goto err;
            }

            hash_str = json_object_get_string(testobj, "h");
            if (!hash_str) {
                ACVP_LOG_ERR("Failed to include h. ");
                rv = ACVP_MISSING_ARG;
                goto err;
            }

            session_id_str = json_object_get_string(testobj, "sessionId");
            if (!session_id_str) {
                ACVP_LOG_ERR("Failed to include sessionId. ");
                rv = ACVP_MISSING_ARG;
                goto err;
            }

            ACVP_LOG_INFO("        Test case: %d", j);
            ACVP_LOG_INFO("             tcId: %d", tc_id);
            ACVP_LOG_INFO("                k: %s", shared_secret_str);
            ACVP_LOG_INFO("                h: %s", hash_str);
            ACVP_LOG_INFO("       session_id: %s", session_id_str);

            /*
             * Create a new test case in the response
             */
            r_tval = json_value_init_object();
            r_tobj = json_value_get_object(r_tval);

            json_object_set_number(r_tobj, "tcId", tc_id);

            /*
             * Setup the test case data that will be passed down to
             * the crypto module.
             */
            rv = acvp_kdf135_ssh_init_tc(ctx, &stc, tc_id, alg_id,
                                         sha_type, e_key_len, i_key_len, iv_len, hash_len,
                                         shared_secret_str, hash_str, session_id_str);
            if (rv != ACVP_SUCCESS) {
                acvp_kdf135_ssh_release_tc(&stc);
                json_value_free(r_tval);
                goto err;
            }

            /* Process the current test vector... */
            if ((cap->crypto_handler)(&tc)) {
                ACVP_LOG_ERR("crypto module failed the KDF SSH operation");
                acvp_kdf135_ssh_release_tc(&stc);
                rv = ACVP_CRYPTO_MODULE_FAIL;
                json_value_free(r_tval);
                goto err;
            }

            /*
             * Output the test case results using JSON
             */
            rv = acvp_kdf135_ssh_output_tc(ctx, &stc, r_tobj);
            if (rv != ACVP_SUCCESS) {
                ACVP_LOG_ERR("JSON output failure in hash module");
                acvp_kdf135_ssh_release_tc(&stc);
                json_value_free(r_tval);
                goto err;
            }
            /*
             * Release all the memory associated with the test case
             */
            acvp_kdf135_ssh_release_tc(&stc);

            /* Append the test response value to array */
            json_array_append_value(r_tarr, r_tval);
        }
        json_array_append_value(r_garr, r_gval);
    }

    json_array_append_value(reg_arry, r_vs_val);

    json_result = json_serialize_to_string_pretty(ctx->kat_resp, NULL);
    if (ctx->debug == ACVP_LOG_LVL_VERBOSE) {
        printf("\n\n%s\n\n", json_result);
    } else {
        ACVP_LOG_INFO("\n\n%s\n\n", json_result);
    }
    json_free_serialized_string(json_result);
    rv = ACVP_SUCCESS;

err:
    if (rv != ACVP_SUCCESS) {
        acvp_release_json(r_vs_val, r_gval);
    }
    return rv;
}
Пример #24
0
/*
 * This function uses libcurl to send a simple HTTP POST
 * request with no Content-Type header.
 * TLS peer verification is enabled, but not HTTP authentication.
 * The parameters are:
 *
 * ctx: Ptr to ACVP_CTX, which contains the server name
 * url: URL to use for the GET request
 * data: data to POST to the server
 * writefunc: Function pointer to handle writing the data
 *            from the HTTP body received from the server.
 *
 * Return value is the HTTP status value from the server
 *	    (e.g. 200 for HTTP OK)
 */
static long acvp_curl_http_post(ACVP_CTX *ctx, char *url, char *data, int data_len) {
    long http_code = 0;
    CURL *hnd;
    CURLcode crv;
    struct curl_slist *slist;
    char user_agent_str[USER_AGENT_STR_MAX + 1];

    /*
     * Set the Content-Type header in the HTTP request
     */
    slist = NULL;
    slist = curl_slist_append(slist, "Content-Type:application/json");

    /*
     * Create the Authorzation header if needed
     */
    slist = acvp_add_auth_hdr(ctx, slist);

    ctx->curl_read_ctr = 0;

    /*
     * Create the HTTP User Agent value
     */
    snprintf(user_agent_str, USER_AGENT_STR_MAX, "libacvp/%s", ACVP_VERSION);

    /*
     * Setup Curl
     */
    hnd = curl_easy_init();
    curl_easy_setopt(hnd, CURLOPT_URL, url);
    curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
    curl_easy_setopt(hnd, CURLOPT_USERAGENT, user_agent_str);
    curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist);
    curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
    curl_easy_setopt(hnd, CURLOPT_POST, 1L);
    curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, data);
    curl_easy_setopt(hnd, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)data_len);
    curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
    curl_easy_setopt(hnd, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);

    /*
     * Always verify the server
     */
    curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 1L);
    if (ctx->cacerts_file) {
        curl_easy_setopt(hnd, CURLOPT_CAINFO, ctx->cacerts_file);
        curl_easy_setopt(hnd, CURLOPT_CERTINFO, 1L);
    }

    /*
     * Mutual-auth
     */
    if (ctx->tls_cert && ctx->tls_key) {
        curl_easy_setopt(hnd, CURLOPT_SSLCERTTYPE, "PEM");
        curl_easy_setopt(hnd, CURLOPT_SSLCERT, ctx->tls_cert);
        curl_easy_setopt(hnd, CURLOPT_SSLKEYTYPE, "PEM");
        curl_easy_setopt(hnd, CURLOPT_SSLKEY, ctx->tls_key);
    }

    /*
     * To record the HTTP data recieved from the server,
     * set the callback function.
     */
    curl_easy_setopt(hnd, CURLOPT_WRITEDATA, ctx);
    curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, &acvp_curl_write_callback);

    if (ctx->curl_buf) {
        /* Clear the HTTP buffer for next server response */
        memzero_s(ctx->curl_buf, ACVP_CURL_BUF_MAX);
    }

    /*
     * Send the HTTP POST request
     */
    crv = curl_easy_perform(hnd);
    if (crv != CURLE_OK) {
        ACVP_LOG_ERR("Curl failed with code %d (%s)\n", crv, curl_easy_strerror(crv));
    }

    /*
     * Get the HTTP reponse status code from the server
     */
    curl_easy_getinfo(hnd, CURLINFO_RESPONSE_CODE, &http_code);

    curl_easy_cleanup(hnd);
    hnd = NULL;
    curl_slist_free_all(slist);
    slist = NULL;

    return http_code;
}