Example #1
0
File: prf.c Project: Deadolus/ecc
/*
	Psuedo-random function.  TLS uses this for key generation and hashing
*/
int32_t prf(const unsigned char *sec, uint16_t secLen,
				const unsigned char *seed, uint16_t seedLen,
				unsigned char *out, uint16_t outLen)
{
	const unsigned char	*s1, *s2;
	unsigned char	md5out[SSL_MAX_KEY_BLOCK_SIZE];
	unsigned char	sha1out[SSL_MAX_KEY_BLOCK_SIZE];
	int32_t			rc = PS_FAIL;
	uint16_t		sLen, i;

	psAssert(outLen <= SSL_MAX_KEY_BLOCK_SIZE);

	sLen = (secLen / 2) + (secLen % 2);
	s1 = sec;
	s2 = (sec + sLen) - (secLen % 2);
	if ((rc = pMd5(s1, sLen, seed, seedLen, md5out, outLen)) < 0) {
		goto L_RETURN;
	}
	if ((rc = pSha1(s2, sLen, seed, seedLen, sha1out, outLen)) < 0) {
		goto L_RETURN;
	}
	for (i = 0; i < outLen; i++) {
		out[i] = md5out[i] ^ sha1out[i];
	}
	rc = outLen;
L_RETURN:
	memzero_s(md5out, SSL_MAX_KEY_BLOCK_SIZE);
	memzero_s(sha1out, SSL_MAX_KEY_BLOCK_SIZE);
	return rc;
}
Example #2
0
File: prf.c Project: Deadolus/ecc
/*
	SHA1 portion of the prf
*/
__inline static int32_t pSha1(const unsigned char *key, uint16_t keyLen,
					const unsigned char *text, uint16_t textLen,
					unsigned char *out, uint16_t outLen)
{
	psHmacSha1_t	ctx;
	unsigned char	a[SHA1_HASH_SIZE];
	unsigned char	mac[SHA1_HASH_SIZE];
	unsigned char	hmacKey[SHA1_HASH_SIZE];
	int32_t			rc = PS_FAIL;
	uint16_t		hmacKeyLen, i, keyIter;

	for (keyIter = 1; (uint16_t)(SHA1_HASH_SIZE * keyIter) < outLen;) {
		keyIter++;
	}
	if ((rc = psHmacSha1(key, keyLen, text, textLen, a,
			hmacKey, &hmacKeyLen)) < 0) {
		goto L_RETURN;
	}
	if (hmacKeyLen != keyLen) {
/*
		Support for keys larger than 64 bytes.  Must take the hash of
		the original key in these cases which is indicated by different
		outgoing values from the passed in key and keyLen values
*/
		psAssert(keyLen > 64);
		/* Typecast is OK, we don't update key below */
		key = (const unsigned char *)hmacKey;
		keyLen = hmacKeyLen;
	}
	for (i = 0; i < keyIter; i++) {
		if ((rc = psHmacSha1Init(&ctx, key, keyLen)) < 0) {
			goto L_RETURN;
		}
		psHmacSha1Update(&ctx, a, SHA1_HASH_SIZE);
		psHmacSha1Update(&ctx, text, textLen);
		psHmacSha1Final(&ctx, mac);
		if (i == keyIter - 1) {
			memcpy(out + (SHA1_HASH_SIZE * i), mac,
				outLen - (SHA1_HASH_SIZE * i));
		} else {
			memcpy(out + (SHA1_HASH_SIZE * i), mac, SHA1_HASH_SIZE);
			if ((rc = psHmacSha1(key, keyLen, a, SHA1_HASH_SIZE, a,
					hmacKey, &hmacKeyLen)) < 0) {
				goto L_RETURN;
			}
		}
	}
	rc = PS_SUCCESS;
L_RETURN:
	memzero_s(a, SHA1_HASH_SIZE);
	memzero_s(mac, SHA1_HASH_SIZE);
	memzero_s(hmacKey, SHA1_HASH_SIZE);
	if (rc < 0) {
		memzero_s(out, outLen);	/* zero any partial result on error */
	}
	return rc;
}
Example #3
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;
}
Example #4
0
/*
 * This function simply releases the data associated with
 * a test case.
 */
static ACVP_RESULT acvp_cmac_release_tc(ACVP_CMAC_TC *stc) {
    if (stc->msg) free(stc->msg);
    if (stc->mac) free(stc->mac);
    if (stc->key) free(stc->key);
    if (stc->key2) free(stc->key2);
    if (stc->key3) free(stc->key3);
    memzero_s(stc, sizeof(ACVP_CMAC_TC));

    return ACVP_SUCCESS;
}
Example #5
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;
}
Example #6
0
static ACVP_RESULT acvp_kdf135_ikev1_release_tc(ACVP_KDF135_IKEV1_TC *stc) {
    if (stc->init_nonce) { free(stc->init_nonce); }
    if (stc->resp_nonce) { free(stc->resp_nonce); }
    if (stc->init_ckey) { free(stc->init_ckey); }
    if (stc->resp_ckey) { free(stc->resp_ckey); }
    if (stc->gxy) { free(stc->gxy); }
    if (stc->psk) { free(stc->psk); }
    if (stc->s_key_id) { free(stc->s_key_id); }
    if (stc->s_key_id_d) { free(stc->s_key_id_d); }
    if (stc->s_key_id_a) { free(stc->s_key_id_a); }
    if (stc->s_key_id_e) { free(stc->s_key_id_e); }
    memzero_s(stc, sizeof(ACVP_KDF135_IKEV1_TC));
    return ACVP_SUCCESS;
}
Example #7
0
/*
 * This function simply releases the data associated with
 * a test case.
 */
static ACVP_RESULT acvp_kdf135_srtp_release_tc(ACVP_KDF135_SRTP_TC *stc) {
    if (stc->kdr) free(stc->kdr);
    if (stc->master_key) free(stc->master_key);
    if (stc->master_salt) free(stc->master_salt);
    if (stc->index) free(stc->index);
    if (stc->srtcp_index) free(stc->srtcp_index);
    if (stc->srtp_ke) free(stc->srtp_ke);
    if (stc->srtp_ka) free(stc->srtp_ka);
    if (stc->srtp_ks) free(stc->srtp_ks);
    if (stc->srtcp_ke) free(stc->srtcp_ke);
    if (stc->srtcp_ka) free(stc->srtcp_ka);
    if (stc->srtcp_ks) free(stc->srtcp_ks);
    memzero_s(stc, sizeof(ACVP_KDF135_SRTP_TC));
    return ACVP_SUCCESS;
}
Example #8
0
/*
 * This function simply releases the data associated with
 * a test case.
 */
static ACVP_RESULT acvp_kdf135_ssh_release_tc(ACVP_KDF135_SSH_TC *stc) {
    if (stc->shared_secret_k) free(stc->shared_secret_k);
    if (stc->hash_h) free(stc->hash_h);
    if (stc->session_id) free(stc->session_id);
    if (stc->cs_init_iv) free(stc->cs_init_iv);
    if (stc->sc_init_iv) free(stc->sc_init_iv);
    if (stc->cs_encrypt_key) free(stc->cs_encrypt_key);
    if (stc->sc_encrypt_key) free(stc->sc_encrypt_key);
    if (stc->cs_integrity_key) free(stc->cs_integrity_key);
    if (stc->sc_integrity_key) free(stc->sc_integrity_key);

    memzero_s(stc, sizeof(ACVP_KDF135_SSH_TC));

    return ACVP_SUCCESS;
}
Example #9
0
File: prf.c Project: Deadolus/ecc
/*
	Psuedo-random function.  TLS uses this for key generation and hashing
*/
int32_t prf2(const unsigned char *sec, uint16_t secLen,
				const unsigned char *seed, uint16_t seedLen,
				unsigned char *out, uint16_t outLen, uint32_t flags)
{
	unsigned char	sha2out[SSL_MAX_KEY_BLOCK_SIZE];
	int32_t			rc;
	uint16_t		i;

	psAssert(outLen <= SSL_MAX_KEY_BLOCK_SIZE);

	if ((rc = pSha2(sec, secLen, seed, seedLen, sha2out, outLen, flags)) < 0) {
		return rc;
	}
	/* Copy out of tmp buffer because outLen typically less than multiple of
		prf block size */
	for (i = 0; i < outLen; i++) {
		out[i] = sha2out[i];
	}
	memzero_s(sha2out, SSL_MAX_KEY_BLOCK_SIZE);
	return outLen;
}
Example #10
0
File: prf.c Project: Deadolus/ecc
/*
	SHA2 prf
*/
__inline static int32_t pSha2(const unsigned char *key, uint16_t keyLen,
					const unsigned char *text, uint16_t textLen,
					unsigned char *out, uint16_t outLen, uint32_t flags)
{
	/* Use a union to save a bit of stack space */
	union {
#ifdef USE_SHA384
		psHmacSha384_t		sha384;
#endif
		psHmacSha256_t		sha256;
	} u;
	unsigned char		a[SHA384_HASH_SIZE];
	unsigned char		mac[SHA384_HASH_SIZE];
	unsigned char		hmacKey[SHA384_HASH_SIZE];
	int32_t				rc = PS_FAIL;
	uint16_t			hashSize, hmacKeyLen, i, keyIter;

#ifdef USE_SHA384
	if (flags & CRYPTO_FLAGS_SHA3) {
		hashSize = SHA384_HASH_SIZE;
		if ((rc = psHmacSha384(key, keyLen, text, textLen, a,
				hmacKey, &hmacKeyLen)) < 0) {
			goto L_RETURN;
		}
	} else
#endif
	{

		hashSize = SHA256_HASH_SIZE;
		if ((rc = psHmacSha256(key, keyLen, text, textLen, a,
				hmacKey, &hmacKeyLen)) < 0) {
			goto L_RETURN;
		}
	}
	for (keyIter = 1; (uint16_t)(hashSize * keyIter) < outLen;) {
		keyIter++;
	}
	if (hmacKeyLen != keyLen) {
/*
		Support for keys larger than 64 bytes.  Must take the hash of
		the original key in these cases which is indicated by different
		outgoing values from the passed in key and keyLen values
*/
		psAssert(keyLen > 64);
		/* Typecast is OK, we don't update key below */
		key = (const unsigned char *)hmacKey;
		keyLen = hmacKeyLen;
	}
	for (i = 0; i < keyIter; i++) {
#ifdef USE_SHA384
		if (flags & CRYPTO_FLAGS_SHA3) {
			if ((rc = psHmacSha384Init(&u.sha384, key, keyLen)) < 0) {
				goto L_RETURN;
			}
			psHmacSha384Update(&u.sha384, a, hashSize);
			psHmacSha384Update(&u.sha384, text, textLen);
			psHmacSha384Final(&u.sha384, mac);
		} else
#endif
		{
			if ((rc = psHmacSha256Init(&u.sha256, key, keyLen)) < 0) {
				goto L_RETURN;
			}
			psHmacSha256Update(&u.sha256, a, hashSize);
			psHmacSha256Update(&u.sha256, text, textLen);
			psHmacSha256Final(&u.sha256, mac);
		}
		if (i == keyIter - 1) {
			memcpy(out + (hashSize * i), mac,
				outLen - (hashSize * i));
		} else {
			memcpy(out + (hashSize * i), mac, hashSize);
#ifdef USE_SHA384
			if (flags & CRYPTO_FLAGS_SHA3) {
				if ((rc = psHmacSha384(key, keyLen, a, hashSize, a,
						hmacKey, &hmacKeyLen)) < 0) {
					goto L_RETURN;
				}
			} else
#endif
			{
				if ((rc = psHmacSha256(key, keyLen, a, hashSize, a,
						hmacKey, &hmacKeyLen)) < 0) {
					goto L_RETURN;
				}
			}
		}
	}
	rc =  PS_SUCCESS;
L_RETURN:
	memzero_s(a, SHA384_HASH_SIZE);
	memzero_s(mac, SHA384_HASH_SIZE);
	memzero_s(hmacKey, SHA384_HASH_SIZE);
	if (rc < 0) {
		memzero_s(out, outLen);	/* zero any partial result on error */
	}
	return rc;
}
Example #11
0
/*
 * This function provides the primary entry point into
 * this module.  It's used by the EST client to read the
 * HTTP response from the server.  The data is read from
 * the SSL context and HTTP parsing is invoked.
 *
 * If EST_ERR_NONE is returned then the raw_buf buffer must
 * be freed by the caller, otherwise, it is freed here.
 */
EST_ERROR est_io_get_response (EST_CTX *ctx, SSL *ssl, EST_OPERATION op,
                               unsigned char **buf, int *payload_len)
{
    int rv = EST_ERR_NONE;
    HTTP_HEADER *hdrs;
    int hdr_cnt;
    int http_status;
    unsigned char *raw_buf, *payload_buf, *payload;    
    int raw_len = 0;
    

    raw_buf = malloc(EST_CA_MAX);
    if (raw_buf == NULL) {
        EST_LOG_ERR("Unable to allocate memory");
        return EST_ERR_MALLOC;
    }
    memzero_s(raw_buf, EST_CA_MAX);
    payload = raw_buf;
    
    /*
     * Read the raw data from the SSL connection
     */
    rv = est_io_read_raw(ssl, raw_buf, EST_CA_MAX, &raw_len, ctx->read_timeout);
    if (rv != EST_ERR_NONE) {
        EST_LOG_INFO("No valid response to process");
        free(raw_buf);
        return (rv);
    }
    if (raw_len <= 0) {
        EST_LOG_WARN("Received empty HTTP response from server");
        free(raw_buf);
        return (EST_ERR_HTTP_NOT_FOUND);
    }
    EST_LOG_INFO("Read %d bytes of HTTP data", raw_len);
    
    /*
     * Parse the HTTP header to get the status
     * Look for status 200 for success
     */
    http_status = est_io_parse_response_status_code(raw_buf);
    ctx->last_http_status = http_status;
    hdrs = parse_http_headers(&payload, &hdr_cnt);
    EST_LOG_INFO("HTTP status %d received", http_status);

    /*
     * Check the Status header first to see
     * if the server accepted our request.
     */
    switch (http_status) {
    case 200:
        /* Server reported OK, nothing to do */
        break;
    case 204:
    case 404:
        EST_LOG_ERR("Server responded with 204/404, no content or not found");
        if (op == EST_OP_CSRATTRS) {
	    rv = EST_ERR_NONE;
        } else if (http_status == 404) {
            rv = EST_ERR_HTTP_NOT_FOUND;            
        } else {
            rv = EST_ERR_UNKNOWN;
        }
        break;
    case 202:
        /* Server is asking for a retry */
        EST_LOG_INFO("EST server responded with retry-after");
        rv = est_io_parse_http_retry_after_resp(ctx, hdrs, hdr_cnt);
        break;
    case 400:
        EST_LOG_ERR("HTTP response from EST server was BAD REQUEST");
        rv = EST_ERR_HTTP_BAD_REQ;
	break;
    case 401:
        /* Server is requesting user auth credentials */
        EST_LOG_INFO("EST server requesting user authentication");

        /* Check if we've already tried authenticating, if so, then bail
         * First time through, auth_mode will be set to NONE
         */
        if (ctx->auth_mode == AUTH_DIGEST ||
            ctx->auth_mode == AUTH_BASIC ||
            ctx->auth_mode == AUTH_TOKEN) {
            ctx->auth_mode = AUTH_FAIL;
            rv = EST_ERR_AUTH_FAIL;
            break;
        }
        est_io_parse_http_auth_request(ctx, hdrs, hdr_cnt);
        rv = EST_ERR_AUTH_FAIL;
        break;
            
    case 423:
        EST_LOG_ERR("Server responded with 423, the content we are attempting to access is locked");
        rv = EST_ERR_HTTP_LOCKED;
        break;
    case -1:
        /* Unsupported HTTP response */
        EST_LOG_ERR("Unsupported HTTP response from EST server (%d)", http_status);
        rv = EST_ERR_UNKNOWN;
        break;
    default:
        /* Some other HTTP response was given, do we want to handle these? */
        EST_LOG_ERR("HTTP response from EST server was %d", http_status);
        rv = EST_ERR_HTTP_UNSUPPORTED;
        break;
    }

    if (rv == EST_ERR_NONE) {
        /*
         * Get the Content-Type and Content-Length headers
         * and verify the HTTP response contains the correct amount
         * of data.
         */
        *payload_len = est_io_check_http_hdrs(hdrs, hdr_cnt, op);
        EST_LOG_INFO("HTTP Content len=%d", *payload_len);

        if (*payload_len > EST_CA_MAX) {
            EST_LOG_ERR("Content Length larger than maximum value of %d.",
                        EST_CA_MAX);
            rv = EST_ERR_UNKNOWN;
            *payload_len = 0;
            *buf = NULL;
        } else if (*payload_len == 0) {
            *payload_len = 0;
            *buf = NULL;
        } else {
            /*
             * Allocate the buffer to hold the payload to be passed back
             */
            payload_buf = malloc(*payload_len);   
            if (!payload_buf) {
                EST_LOG_ERR("Unable to allocate memory");
                free(raw_buf);
                free(hdrs);
                return EST_ERR_MALLOC;
            }
            memcpy_s(payload_buf, *payload_len, payload, *payload_len);
            *buf = payload_buf;
        }
    }
    
    if (raw_buf) {
        free(raw_buf);
    }
    if (hdrs) {
        free(hdrs);
    }
    return (rv);
}
Example #12
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;
}
Example #13
0
/*
 * This function uses libcurl to send a simple HTTP GET
 * 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
 *
 * Return value is the HTTP status value from the server
 *	    (e.g. 200 for HTTP OK)
 */
static long acvp_curl_http_get(ACVP_CTX *ctx, char *url) {
    long http_code = 0;
    CURL *hnd;
    struct curl_slist *slist;
    char user_agent_str[USER_AGENT_STR_MAX + 1];

    slist = NULL;
    /*
     * 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_TCP_KEEPALIVE, 1L);
    curl_easy_setopt(hnd, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
    if (slist) {
        curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist);
    }

    /*
     * 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 GET request
     */
    curl_easy_perform(hnd);

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

    curl_easy_cleanup(hnd);
    hnd = NULL;
    if (slist) {
        curl_slist_free_all(slist);
        slist = NULL;
    }

    return http_code;
}
Example #14
0
static ACVP_RESULT acvp_kdf135_ssh_init_tc(ACVP_CTX *ctx,
                                           ACVP_KDF135_SSH_TC *stc,
                                           unsigned int tc_id,
                                           ACVP_CIPHER alg_id,
                                           ACVP_HASH_ALG sha_type,
                                           unsigned int e_key_len,
                                           unsigned int i_key_len,
                                           unsigned int iv_len,
                                           unsigned int hash_len,
                                           const char *shared_secret_k,
                                           const char *hash_h,
                                           const char *session_id) {
    unsigned int shared_secret_len = 0;
    unsigned int session_id_len = 0;
    ACVP_RESULT rv;

    memzero_s(stc, sizeof(ACVP_KDF135_SSH_TC));

    // Get the byte lengths
    shared_secret_len = strnlen_s(shared_secret_k, ACVP_KDF135_SSH_STR_IN_MAX) / 2;
    session_id_len = strnlen_s(session_id, ACVP_KDF135_SSH_STR_IN_MAX) / 2;

    stc->shared_secret_k = calloc(shared_secret_len, sizeof(unsigned char));
    if (!stc->shared_secret_k) { return ACVP_MALLOC_FAIL; }
    stc->hash_h = calloc(hash_len, sizeof(unsigned char));
    if (!stc->hash_h) { return ACVP_MALLOC_FAIL; }
    stc->session_id = calloc(session_id_len, sizeof(unsigned char));
    if (!stc->session_id) { return ACVP_MALLOC_FAIL; }

    // Convert from hex string to binary
    rv = acvp_hexstr_to_bin(shared_secret_k, (unsigned char *)stc->shared_secret_k,
                            shared_secret_len, NULL);
    if (rv != ACVP_SUCCESS) return rv;

    rv = acvp_hexstr_to_bin(hash_h, (unsigned char *)stc->hash_h, hash_len, NULL);
    if (rv != ACVP_SUCCESS) return rv;

    rv = acvp_hexstr_to_bin(session_id, (unsigned char *)stc->session_id, session_id_len, NULL);
    if (rv != ACVP_SUCCESS) return rv;

    // Allocate answer buffers
    stc->cs_init_iv = calloc(ACVP_KDF135_SSH_IV_MAX, sizeof(unsigned char));
    if (!stc->cs_init_iv) { return ACVP_MALLOC_FAIL; }
    stc->sc_init_iv = calloc(ACVP_KDF135_SSH_IV_MAX, sizeof(unsigned char));
    if (!stc->sc_init_iv) { return ACVP_MALLOC_FAIL; }

    stc->cs_encrypt_key = calloc(ACVP_KDF135_SSH_EKEY_MAX, sizeof(unsigned char));
    if (!stc->cs_encrypt_key) { return ACVP_MALLOC_FAIL; }
    stc->sc_encrypt_key = calloc(ACVP_KDF135_SSH_EKEY_MAX, sizeof(unsigned char));
    if (!stc->sc_encrypt_key) { return ACVP_MALLOC_FAIL; }

    stc->cs_integrity_key = calloc(ACVP_KDF135_SSH_IKEY_MAX, sizeof(unsigned char));
    if (!stc->cs_integrity_key) { return ACVP_MALLOC_FAIL; }
    stc->sc_integrity_key = calloc(ACVP_KDF135_SSH_IKEY_MAX, sizeof(unsigned char));
    if (!stc->sc_integrity_key) { return ACVP_MALLOC_FAIL; }

    stc->tc_id = tc_id;
    stc->cipher = alg_id;
    stc->sha_type = sha_type;
    stc->e_key_len = e_key_len;
    stc->i_key_len = i_key_len;
    stc->iv_len = iv_len;
    stc->shared_secret_len = shared_secret_len;
    stc->hash_len = hash_len;
    stc->session_id_len = session_id_len;

    return ACVP_SUCCESS;
}
Example #15
0
File: tls.c Project: Deadolus/ecc
static int32_t genKeyBlock(ssl_t *ssl)
{
	unsigned char	msSeed[SSL_HS_RANDOM_SIZE * 2 + LABEL_SIZE];
	uint32			reqKeyLen;
	int32_t			rc = PS_FAIL;
	
	memcpy(msSeed, LABEL_KEY_BLOCK, LABEL_SIZE);
	memcpy(msSeed + LABEL_SIZE, ssl->sec.serverRandom,
		SSL_HS_RANDOM_SIZE);
	memcpy(msSeed + LABEL_SIZE + SSL_HS_RANDOM_SIZE,
		ssl->sec.clientRandom, SSL_HS_RANDOM_SIZE);

	/* We must generate enough key material to fill the various keys */
	reqKeyLen = 2 * ssl->cipher->macSize +
				2 * ssl->cipher->keySize +
				2 * ssl->cipher->ivSize;

	/* Ensure there's enough room */
	if (reqKeyLen > SSL_MAX_KEY_BLOCK_SIZE) {
		rc = PS_MEM_FAIL;
		goto L_RETURN;
	}

#ifdef USE_TLS_1_2
	if (ssl->flags & SSL_FLAGS_TLS_1_2) {
		if ((rc = prf2(ssl->sec.masterSecret, SSL_HS_MASTER_SIZE, msSeed,
				(SSL_HS_RANDOM_SIZE * 2) + LABEL_SIZE, ssl->sec.keyBlock,
				reqKeyLen, ssl->cipher->flags)) < 0) {
			goto L_RETURN;
		}
	}
#ifndef USE_ONLY_TLS_1_2
	else {
		if ((rc = prf(ssl->sec.masterSecret, SSL_HS_MASTER_SIZE, msSeed,
				(SSL_HS_RANDOM_SIZE * 2) + LABEL_SIZE, ssl->sec.keyBlock,
				reqKeyLen)) < 0) {
			goto L_RETURN;
		}
	}
#endif
#else
	if ((rc = prf(ssl->sec.masterSecret, SSL_HS_MASTER_SIZE, msSeed,
			(SSL_HS_RANDOM_SIZE * 2) + LABEL_SIZE, ssl->sec.keyBlock,
			reqKeyLen)) < 0) {
		goto L_RETURN;
	}
#endif
	if (ssl->flags & SSL_FLAGS_SERVER) {
		ssl->sec.rMACptr = ssl->sec.keyBlock;
		ssl->sec.wMACptr = ssl->sec.rMACptr + ssl->cipher->macSize;
		ssl->sec.rKeyptr = ssl->sec.wMACptr + ssl->cipher->macSize;
		ssl->sec.wKeyptr = ssl->sec.rKeyptr + ssl->cipher->keySize;
		ssl->sec.rIVptr = ssl->sec.wKeyptr + ssl->cipher->keySize;
		ssl->sec.wIVptr = ssl->sec.rIVptr + ssl->cipher->ivSize;
	} else {
		ssl->sec.wMACptr = ssl->sec.keyBlock;
		ssl->sec.rMACptr = ssl->sec.wMACptr + ssl->cipher->macSize;
		ssl->sec.wKeyptr = ssl->sec.rMACptr + ssl->cipher->macSize;
		ssl->sec.rKeyptr = ssl->sec.wKeyptr + ssl->cipher->keySize;
		ssl->sec.wIVptr = ssl->sec.rKeyptr + ssl->cipher->keySize;
		ssl->sec.rIVptr = ssl->sec.wIVptr + ssl->cipher->ivSize;
	}

	rc = SSL_HS_MASTER_SIZE;

L_RETURN:
	memzero_s(msSeed, sizeof(msSeed));
	if (rc < 0) {
		memzero_s(ssl->sec.masterSecret, SSL_HS_MASTER_SIZE);
		memzero_s(ssl->sec.keyBlock, SSL_MAX_KEY_BLOCK_SIZE);
	}
	return rc;
}
Example #16
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;
}
Example #17
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;
}
Example #18
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;
}
Example #19
0
/*
 * This function parses the authentication tokens from
 * the server when the server is requesting HTTP digest
 * authentication.  The tokens are required to generate
 * a valid authentication response in future HTTP
 * requests.
 */
static EST_ERROR est_io_parse_auth_tokens (EST_CTX *ctx, char *hdr)
{
    int rv = EST_ERR_NONE;
    char *p = hdr;
    char *token = NULL;
    char *value = NULL;
    int diff;
    errno_t safec_rc;

    /*
     * header will come in with the basic or digest field still on the front.
     * skip over it.
     */

    token = HTNextField(&p);

    while ((token = HTNextField(&p))) {
        if (!est_strcasecmp_s(token, "realm")) {
            if ((value = HTNextField(&p))) {
                if (EOK != strncpy_s(ctx->realm, MAX_REALM, value, MAX_REALM)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "nonce")) {
            if ((value = HTNextField(&p))) {
                if (EOK != strncpy_s(ctx->s_nonce, MAX_NONCE, value, MAX_NONCE)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }                
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "qop")) {
            if ((value = HTNextField(&p))) {

                if (value[0] == '\0') {
                    EST_LOG_WARN("Unsupported qop value: %s", value);
                } else {
                    safec_rc = memcmp_s(value, sizeof("auth"), "auth", sizeof("auth"), &diff);
                    if (safec_rc != EOK) {
                        EST_LOG_INFO("memcmp_s error 0x%xO\n", safec_rc);
                    }
                    if (diff && (safec_rc == EOK)) {
                        EST_LOG_WARN("Unsupported qop value: %s", value);
                    }
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "algorithm")) {
            if ((value = HTNextField(&p)) && est_strcasecmp_s(value, "md5")) {
                EST_LOG_ERR("Unsupported digest algorithm: %s", value);
                /*
                 **  We only support MD5 for the moment
                 */
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "error")) {
            if ((value = HTNextField(&p))) {
                if (EOK != strncpy_s(ctx->token_error, MAX_TOKEN_ERROR, value, MAX_TOKEN_ERROR)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else if (!est_strcasecmp_s(token, "error_description")) {
            if ((value = HTNextField(&p))) {
                if (EOK != strncpy_s(ctx->token_error_desc, MAX_TOKEN_ERROR_DESC, value, MAX_TOKEN_ERROR_DESC)) {
                    rv = EST_ERR_INVALID_TOKEN;
                }
            } else {
                rv = EST_ERR_INVALID_TOKEN;
            }
        } else {
            EST_LOG_WARN("Unsupported auth token ignored: %s", token);
        }

        if (rv == EST_ERR_INVALID_TOKEN) {
            memzero_s(ctx->s_nonce, MAX_NONCE+1);
            break;
        }   
    }
    return (rv);
}
Example #20
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;
}