Exemple #1
0
/**
 * Issue command with parameter block and data block
 *
 * @v nii		NII NIC
 * @v op		Operation
 * @v cpb		Command parameter block, or NULL
 * @v cpb_len		Command parameter block length
 * @v db		Data block, or NULL
 * @v db_len		Data block length
 * @ret stat		Status flags, or negative status code
 */
static int nii_issue_cpb_db ( struct nii_nic *nii, unsigned int op, void *cpb,
			      size_t cpb_len, void *db, size_t db_len ) {
	PXE_CDB cdb;

	/* Prepare command descriptor block */
	memset ( &cdb, 0, sizeof ( cdb ) );
	cdb.OpCode = NII_OPCODE ( op );
	cdb.OpFlags = NII_OPFLAGS ( op );
	cdb.CPBaddr = ( ( intptr_t ) cpb );
	cdb.CPBsize = cpb_len;
	cdb.DBaddr = ( ( intptr_t ) db );
	cdb.DBsize = db_len;
	cdb.IFnum = nii->nii->IfNum;

	/* Issue command */
	DBGC2 ( nii, "NII %s issuing %02x:%04x ifnum %d%s%s\n",
		nii->dev.name, cdb.OpCode, cdb.OpFlags, cdb.IFnum,
		( cpb ? " cpb" : "" ), ( db ? " db" : "" ) );
	if ( cpb )
		DBGC2_HD ( nii, cpb, cpb_len );
	if ( db )
		DBGC2_HD ( nii, db, db_len );
	nii->issue ( ( intptr_t ) &cdb );

	/* Check completion status */
	if ( cdb.StatCode != PXE_STATCODE_SUCCESS )
		return -cdb.StatCode;

	/* Return command-specific status flags */
	return ( cdb.StatFlags & ~PXE_STATFLAGS_STATUS_MASK );
}
Exemple #2
0
/**
 * Generate secure pseudo-random data using a single hash function
 *
 * @v tls		TLS session
 * @v digest		Hash function to use
 * @v secret		Secret
 * @v secret_len	Length of secret
 * @v out		Output buffer
 * @v out_len		Length of output buffer
 * @v seeds		( data, len ) pairs of seed data, terminated by NULL
 */
static void tls_p_hash_va ( struct tls_session *tls,
			    struct digest_algorithm *digest,
			    void *secret, size_t secret_len,
			    void *out, size_t out_len,
			    va_list seeds ) {
	uint8_t secret_copy[secret_len];
	uint8_t digest_ctx[digest->ctxsize];
	uint8_t digest_ctx_partial[digest->ctxsize];
	uint8_t a[digest->digestsize];
	uint8_t out_tmp[digest->digestsize];
	size_t frag_len = digest->digestsize;
	va_list tmp;

	/* Copy the secret, in case HMAC modifies it */
	memcpy ( secret_copy, secret, secret_len );
	secret = secret_copy;
	DBGC2 ( tls, "TLS %p %s secret:\n", tls, digest->name );
	DBGC2_HD ( tls, secret, secret_len );

	/* Calculate A(1) */
	hmac_init ( digest, digest_ctx, secret, &secret_len );
	va_copy ( tmp, seeds );
	tls_hmac_update_va ( digest, digest_ctx, tmp );
	va_end ( tmp );
	hmac_final ( digest, digest_ctx, secret, &secret_len, a );
	DBGC2 ( tls, "TLS %p %s A(1):\n", tls, digest->name );
	DBGC2_HD ( tls, &a, sizeof ( a ) );

	/* Generate as much data as required */
	while ( out_len ) {
		/* Calculate output portion */
		hmac_init ( digest, digest_ctx, secret, &secret_len );
		hmac_update ( digest, digest_ctx, a, sizeof ( a ) );
		memcpy ( digest_ctx_partial, digest_ctx, digest->ctxsize );
		va_copy ( tmp, seeds );
		tls_hmac_update_va ( digest, digest_ctx, tmp );
		va_end ( tmp );
		hmac_final ( digest, digest_ctx,
			     secret, &secret_len, out_tmp );

		/* Copy output */
		if ( frag_len > out_len )
			frag_len = out_len;
		memcpy ( out, out_tmp, frag_len );
		DBGC2 ( tls, "TLS %p %s output:\n", tls, digest->name );
		DBGC2_HD ( tls, out, frag_len );

		/* Calculate A(i) */
		hmac_final ( digest, digest_ctx_partial,
			     secret, &secret_len, a );
		DBGC2 ( tls, "TLS %p %s A(n):\n", tls, digest->name );
		DBGC2_HD ( tls, &a, sizeof ( a ) );

		out += frag_len;
		out_len -= frag_len;
	}
}