예제 #1
0
/*!
 * Create two links using keys allocated in the scc
 *
 * @param         header     The Sahara header value for the descriptor.
 * @param         in1        The first input buffer (or NULL)
 * @param         in1_length Size of @a in1
 * @param[out]    in2        The second input buffer (or NULL)
 * @param         in2_length Size of @a in2
 * @param         mu         Memory functions
 * @param[in,out] desc_chain Chain to start or append to
 *
 * @return    A return code of type #fsl_shw_return_t.
 */
fsl_shw_return_t add_key_key_desc(uint32_t header,
				  fsl_shw_sko_t * key_info1,
				  fsl_shw_sko_t * key_info2,
				  const sah_Mem_Util * mu,
				  sah_Head_Desc ** desc_chain)
{
	fsl_shw_return_t status;
	sah_Link *link1 = NULL;
	sah_Link *link2 = NULL;

	status = sah_Create_Key_Link(mu, &link1, key_info1);

	if (status == FSL_RETURN_OK_S) {
		status = sah_Create_Key_Link(mu, &link2, key_info2);
	}

	if (status != FSL_RETURN_OK_S) {
		if (link1 != NULL) {
			sah_Destroy_Link(mu, link1);
		}
		if (link2 != NULL) {
			sah_Destroy_Link(mu, link2);
		}
	} else {
		status = sah_Append_Desc(mu, desc_chain, header, link1, link2);
	}

	return status;
}
예제 #2
0
/*!
 * Add descriptor where link1 is input buffer, link2 is output buffer.
 *
 * @param         header     The Sahara header value for the descriptor.
 * @param         in         The input buffer
 * @param         in_length  Size of the input buffer
 * @param[out]    out        The output buffer
 * @param         out_length Size of the output buffer
 * @param         mu         Memory functions
 * @param[in,out] desc_chain Chain to start or append to
 *
 * @return    A return code of type #fsl_shw_return_t.
 */
fsl_shw_return_t add_in_out_desc(uint32_t header,
				 const uint8_t * in, uint32_t in_length,
				 uint8_t * out, uint32_t out_length,
				 const sah_Mem_Util * mu,
				 sah_Head_Desc ** desc_chain)
{
	fsl_shw_return_t status = FSL_RETURN_OK_S;
	sah_Link *link1 = NULL;
	sah_Link *link2 = NULL;

	if (in != NULL) {
		status = sah_Create_Link(mu, &link1,
					 (sah_Oct_Str) in, in_length,
					 SAH_USES_LINK_DATA);
	}

	if ((status == FSL_RETURN_OK_S) && (out != NULL)) {
		status = sah_Create_Link(mu, &link2,
					 (sah_Oct_Str) out, out_length,
					 SAH_OUTPUT_LINK | SAH_USES_LINK_DATA);
	}

	if (status != FSL_RETURN_OK_S) {
		if (link1 != NULL) {
			sah_Destroy_Link(mu, link1);
		}
		if (link2 != NULL) {
			sah_Destroy_Link(mu, link2);
		}
	} else {
		status = sah_Append_Desc(mu, desc_chain, header, link1, link2);
	}

	return status;
}
예제 #3
0
/*!
 * Add descriptor where both links are inputs, the second one being a key.
 *
 * @param         header     The Sahara header value for the descriptor.
 * @param         in1        The first input buffer (or NULL)
 * @param         in1_length Size of @a in1
 * @param[out]    in2        The second input buffer (or NULL)
 * @param         in2_length Size of @a in2
 * @param         mu         Memory functions
 * @param[in,out] desc_chain Chain to start or append to
 *
 * @return    A return code of type #fsl_shw_return_t.
 */
fsl_shw_return_t add_in_key_desc(uint32_t header,
				 const uint8_t * in1,
				 uint32_t in1_length,
				 fsl_shw_sko_t * key_info,
				 const sah_Mem_Util * mu,
				 sah_Head_Desc ** desc_chain)
{
	fsl_shw_return_t status = FSL_RETURN_OK_S;
	sah_Link *link1 = NULL;
	sah_Link *link2 = NULL;

	if (in1 != NULL) {
		status = sah_Create_Link(mu, &link1,
					 (sah_Oct_Str) in1, in1_length,
					 SAH_USES_LINK_DATA);
	}

	if (status == FSL_RETURN_OK_S) {
		status = sah_Create_Key_Link(mu, &link2, key_info);
	}

	if (status != FSL_RETURN_OK_S) {
		if (link1 != NULL) {
			sah_Destroy_Link(mu, link1);
		}
		if (link2 != NULL) {
			sah_Destroy_Link(mu, link2);
		}
	} else {
		status = sah_Append_Desc(mu, desc_chain, header, link1, link2);
	}

	return status;
}
예제 #4
0
/*!
 * Releases the memory allocated by the Security Function library for
 * descriptors, links and any internally allocated memory referenced in the
 * given chain. Note that memory allocated by user applications is not
 * released.
 *
 * @post The @a desc_head pointer will be set to NULL to prevent further use.
 *
 * @brief   Destroy a descriptor chain and free memory of associated links
 *
 * @param  mu Memory functions
 * @param  desc_head Pointer to head of descriptor chain to be freed
 *
 * @return none
 */
void sah_Descriptor_Chain_Destroy(const sah_Mem_Util * mu,
				  sah_Head_Desc ** desc_head)
{
	sah_Desc *desc_ptr = &(*desc_head)->desc;
	sah_Head_Desc *desc_head_ptr = (sah_Head_Desc *) desc_ptr;

	while (desc_ptr != NULL) {
		register sah_Desc *next_desc_ptr;

		if (desc_ptr->ptr1 != NULL) {
			sah_Destroy_Link(mu, desc_ptr->ptr1);
		}
		if (desc_ptr->ptr2 != NULL) {
			sah_Destroy_Link(mu, desc_ptr->ptr2);
		}

		next_desc_ptr = desc_ptr->next;

		/* Be sure to free head descriptor as such */
		if (desc_ptr == (sah_Desc *) desc_head_ptr) {
			mu->mu_free_head_desc(mu->mu_ref, desc_head_ptr);
		} else {
			mu->mu_free_desc(mu->mu_ref, desc_ptr);
		}

		desc_ptr = next_desc_ptr;
	}

	*desc_head = NULL;
}
예제 #5
0
/*!
 * Add a Descriptor which will process with CBC the NIST preamble data
 *
 * @param     desc_chain   Current chain
 * @param     user_ctx     User's context
 * @param     auth_ctx     Inf
 * @param     auth_data    Additional auth data for this call
 * @param     auth_data_length   Length in bytes of @a auth_data
 *
 * @return    A return code of type #fsl_shw_return_t.
 */
static inline fsl_shw_return_t add_assoc_preamble(sah_Head_Desc ** desc_chain,
						  fsl_shw_uco_t * user_ctx,
						  fsl_shw_acco_t * auth_ctx,
						  const uint8_t * auth_data,
						  uint32_t auth_data_length)
{
	uint8_t *temp_buf;
	sah_Link *link1 = NULL;
	sah_Link *link2 = NULL;
	fsl_shw_return_t status = FSL_RETURN_OK_S;
	uint32_t cbc_data_length = 0;
	/* Assume AES */
	uint32_t header = SAH_HDR_SKHA_ENC_DEC;

	/* Grab a block big enough for multiple uses so that only one allocate
	 * request needs to be made.
	 */
	temp_buf =
	    user_ctx->mem_util->mu_malloc(user_ctx->mem_util->mu_ref,
					  3 *
					  auth_ctx->auth_info.CCM_ctx_info.
					  block_size_bytes);

	if (temp_buf == NULL) {
		status = FSL_RETURN_NO_RESOURCE_S;
	} else {
		uint32_t temp_buf_flag;

		if (auth_ctx->flags & FSL_ACCO_NIST_CCM) {
			status = process_assoc_from_nist_params(&link1,
								&cbc_data_length,
								user_ctx,
								auth_ctx,
								auth_data,
								auth_data_length,
								&temp_buf);
			/* temp_buf has been referenced (and incremented).  Only 'own' it
			 * once, at its first value.  Since the nist routine called above
			 * bumps it...
			 */
			temp_buf_flag = SAH_USES_LINK_DATA;
		} else {	/* if NIST */
			if (status == FSL_RETURN_OK_S) {
				status =
				    sah_Create_Link(user_ctx->mem_util, &link1,
						    (uint8_t *) auth_data,
						    auth_data_length,
						    SAH_USES_LINK_DATA);
				/* for next/first use of temp_buf */
				temp_buf_flag = SAH_OWNS_LINK_DATA;
			}
			cbc_data_length = auth_data_length;
		}		/* else not NIST */

		/*
		 * Auth data links have been created.  Now create link for the
		 * useless output of the CBC calculation.
		 */
		if (status == FSL_RETURN_OK_S) {
			status = sah_Create_Link(user_ctx->mem_util, &link2,
						 temp_buf,
						 auth_ctx->auth_info.
						 CCM_ctx_info.block_size_bytes,
						 temp_buf_flag |
						 SAH_OUTPUT_LINK);
		}
		temp_buf += auth_ctx->auth_info.CCM_ctx_info.block_size_bytes;

		cbc_data_length -=
		    auth_ctx->auth_info.CCM_ctx_info.block_size_bytes;

		if (cbc_data_length != 0) {
			while ((status == FSL_RETURN_OK_S)
			       && (cbc_data_length != 0)) {
				uint32_t linklen =
				    (cbc_data_length >
				     CBC_BUF_LEN) ? CBC_BUF_LEN :
				    cbc_data_length;

				status =
				    sah_Append_Link(user_ctx->mem_util, link2,
						    cbc_buffer, linklen,
						    SAH_USES_LINK_DATA |
						    SAH_OUTPUT_LINK);
				cbc_data_length -= linklen;
			}
		}

		if (status != FSL_RETURN_OK_S) {
			if (link1 != NULL) {
				sah_Destroy_Link(user_ctx->mem_util, link1);
			}
			if (link2 != NULL) {
				sah_Destroy_Link(user_ctx->mem_util, link2);
			}
		} else {
			/* Header to set up crank through auth data */
			status = sah_Append_Desc(user_ctx->mem_util, desc_chain,
						 header, link1, link2);
		}
	}

	return status;
}
예제 #6
0
/*!
 * Create and populate a single descriptor
 *
 * The pointer and length fields will be be set based on the chains passed in
 * as @a link1 and @a link2.
 *
 * @param  mu         Memory utility suite
 * @param  desc       Location to store pointer of new descriptor
 * @param  head_desc  Non-zero if this will be first in chain; zero otherwise
 * @param  header     The Sahara header value to store in the descriptor
 * @param  link1      A value (or NULL) for the first ptr
 * @param  link2      A value (or NULL) for the second ptr
 *
 * @post  If allocation succeeded, the @a link1 and @link2 will be linked into
 *        the descriptor.  If allocation failed, those link structues will be
 *        freed, and the @a desc will be unchanged.
 *
 * @return    A return code of type #fsl_shw_return_t.
 */
static fsl_shw_return_t sah_Create_Desc(const sah_Mem_Util * mu,
					sah_Desc ** desc,
					int head_desc,
					uint32_t header,
					sah_Link * link1, sah_Link * link2)
{
	fsl_shw_return_t status = FSL_RETURN_NO_RESOURCE_S;
#ifdef DIAG_SECURITY_FUNC
	char diag[50];
#endif				/*DIAG_SECURITY_FUNC */

	if (head_desc != 0) {
		*desc = (sah_Desc *) mu->mu_alloc_head_desc(mu->mu_ref);
	} else {
		*desc = mu->mu_alloc_desc(mu->mu_ref);
	}

	/* populate descriptor if memory allocation successful */
	if ((*desc) != NULL) {
		sah_Link *temp_link;

		status = FSL_RETURN_OK_S;
		(*desc)->header = header;

		temp_link = (*desc)->ptr1 = link1;
		(*desc)->len1 = 0;
		while (temp_link != NULL) {
			(*desc)->len1 += temp_link->len;
			temp_link = temp_link->next;
		}

		temp_link = (*desc)->ptr2 = link2;
		(*desc)->len2 = 0;
		while (temp_link != NULL) {
			(*desc)->len2 += temp_link->len;
			temp_link = temp_link->next;
		}

		(*desc)->next = NULL;

#ifdef DIAG_SECURITY_FUNC
		LOG_DIAG("Created Desc");
		LOG_DIAG("------------");
		sprintf(diag, " address       = 0x%x", (int)*desc);
		LOG_DIAG(diag);
		sprintf(diag, " desc->header  = 0x%x", (*desc)->header);
		LOG_DIAG(diag);
		sprintf(diag, " desc->len1    = %d", (*desc)->len1);
		LOG_DIAG(diag);
		sprintf(diag, " desc->ptr1    = 0x%x", (int)((*desc)->ptr1));
		LOG_DIAG(diag);
		sprintf(diag, " desc->len2    = %d", (*desc)->len2);
		LOG_DIAG(diag);
		sprintf(diag, " desc->ptr2    = 0x%x", (int)((*desc)->ptr2));
		LOG_DIAG(diag);
		sprintf(diag, " desc->next    = 0x%x", (int)((*desc)->next));
		LOG_DIAG(diag);
#endif				/*DIAG_SECURITY_FUNC */
	} else {
#ifdef DIAG_SECURITY_FUNC
		LOG_DIAG("Allocation of memory for sah_Desc failed!\n");
#endif				/*DIAG_SECURITY_FUNC */

		/* Destroy the links, otherwise the memory allocated by the Security
		   Function layer for the links (and possibly the data within the links)
		   will be lost */
		if (link1 != NULL) {
			sah_Destroy_Link(mu, link1);
		}
		if (link2 != NULL) {
			sah_Destroy_Link(mu, link2);
		}
	}

	return status;
}
/*!
 * Insert descriptors to calculate ICV = HMAC(key=T, data=LEN|ALG|KEY')
 *
 * @param  user_ctx      User's context for this operation
 * @param  desc_chain    Descriptor chain to append to
 * @param  t_key_info    T's key object
 * @param  black_key     Beginning of Black Key region
 * @param  key_length    Number of bytes of key' there are in @c black_key
 * @param[out] hmac      Location to store ICV.  Will be tagged "USES" so
 *                       sf routines will not try to free it.
 *
 * @return    A return code of type #fsl_shw_return_t.
 */
static inline fsl_shw_return_t create_icv_calc(fsl_shw_uco_t * user_ctx,
					       sah_Head_Desc ** desc_chain,
					       fsl_shw_sko_t * t_key_info,
					       const uint8_t * black_key,
					       uint32_t key_length,
					       uint8_t * hmac)
{
	fsl_shw_return_t sah_code;
	uint32_t header;
	sah_Link *link1 = NULL;
	sah_Link *link2 = NULL;

	/* Load up T as key for the HMAC */
	header = (SAH_HDR_MDHA_SET_MODE_MD_KEY	/* #6 */
		  ^ sah_insert_mdha_algorithm_sha256
		  ^ sah_insert_mdha_init ^ sah_insert_mdha_hmac ^
		  sah_insert_mdha_pdata ^ sah_insert_mdha_mac_full);
	sah_code = sah_add_in_key_desc(header, NULL, 0, t_key_info,	/* Reference T in RED */
				       user_ctx->mem_util, desc_chain);
	if (sah_code != FSL_RETURN_OK_S) {
		goto out;
	}

	/* Previous step loaded key; Now set up to hash the data */
	header = SAH_HDR_MDHA_HASH;	/* #10 */

	/* Input - start with ownerid */
	sah_code = sah_Create_Link(user_ctx->mem_util, &link1,
				   (void *)&t_key_info->userid,
				   sizeof(t_key_info->userid),
				   SAH_USES_LINK_DATA);
	if (sah_code != FSL_RETURN_OK_S) {
		goto out;
	}

	/* Still input  - Append black-key fields len, alg, key' */
	sah_code = sah_Append_Link(user_ctx->mem_util, link1,
				   (void *)black_key + LENGTH_OFFSET,
				   (LENGTH_LENGTH
				    + ALGORITHM_LENGTH
				    + key_length), SAH_USES_LINK_DATA);

	if (sah_code != FSL_RETURN_OK_S) {
		goto out;
	}
	/* Output - computed ICV/HMAC */
	sah_code = sah_Create_Link(user_ctx->mem_util, &link2,
				   hmac, ICV_LENGTH,
				   SAH_USES_LINK_DATA | SAH_OUTPUT_LINK);
	if (sah_code != FSL_RETURN_OK_S) {
		goto out;
	}

	sah_code = sah_Append_Desc(user_ctx->mem_util, desc_chain,
				   header, link1, link2);

      out:
	if (sah_code != FSL_RETURN_OK_S) {
		(void)sah_Destroy_Link(user_ctx->mem_util, link1);
		(void)sah_Destroy_Link(user_ctx->mem_util, link2);
	}

	return sah_code;
}				/* create_icv_calc */
예제 #8
0
/*!
 * Create and run the chain for a symmetric-key operation.
 *
 * @param user_ctx    Who the user is
 * @param key_info    What key is to be used
 * @param sym_ctx     Info details about algorithm
 * @param encrypt     0 = decrypt, non-zero = encrypt
 * @param length      Number of octets at @a in and @a out
 * @param in          Pointer to input data
 * @param out         Location to store output data
 *
 * @return         The status of handing chain to driver,
 *                 or an earlier argument/flag or allocation
 *                 error.
 */
static fsl_shw_return_t do_symmetric(fsl_shw_uco_t * user_ctx,
				     fsl_shw_sko_t * key_info,
				     fsl_shw_scco_t * sym_ctx,
				     cipher_direction_t encrypt,
				     uint32_t length,
				     const uint8_t * in, uint8_t * out)
{
	SAH_SF_DCLS;
	uint8_t *sink = NULL;
	sah_Link *link1 = NULL;
	sah_Link *link2 = NULL;
	sah_Oct_Str ptr1;
	uint32_t size1 = sym_ctx->block_size_bytes;

	SAH_SF_USER_CHECK();

	/* Two different sets of chains, depending on algorithm */
	if (key_info->algorithm == FSL_KEY_ALG_ARC4) {
		if (sym_ctx->flags & FSL_SYM_CTX_INIT) {
			/* Desc. #35 w/ARC4 - start from key */
			header = SAH_HDR_ARC4_SET_MODE_KEY
			    ^ sah_insert_skha_algorithm_arc4;

			DESC_IN_KEY(header, 0, NULL, key_info);
		} else {	/* load SBox */
			/* Desc. #33 w/ARC4 and NO PERMUTE */
			header = SAH_HDR_ARC4_SET_MODE_SBOX
			    ^ sah_insert_skha_no_permute
			    ^ sah_insert_skha_algorithm_arc4;
			DESC_IN_IN(header, 256, sym_ctx->context,
				   3, sym_ctx->context + 256);
		}		/* load SBox */

		/* Add in-out data descriptor to process the data */
		if (length != 0) {
			DESC_IN_OUT(SAH_HDR_SKHA_ENC_DEC, length, in, length,
				    out);
		}

		/* Operation is done ... save what came out? */
		if (sym_ctx->flags & FSL_SYM_CTX_SAVE) {
			/* Desc. #34 - Read SBox, pointers */
			header = SAH_HDR_ARC4_READ_SBOX;
			DESC_OUT_OUT(header, 256, sym_ctx->context,
				     3, sym_ctx->context + 256);
		}
	} else {		/* not ARC4 */
		/* Doing 1- or 2- descriptor chain. */
		/* Desc. #1 and algorithm and mode */
		header = SAH_HDR_SKHA_SET_MODE_IV_KEY
		    ^ sah_insert_skha_mode[sym_ctx->mode]
		    ^ sah_insert_skha_algorithm[key_info->algorithm];

		/* Honor 'no key parity checking' for DES and TDES */
		if ((key_info->flags & FSL_SKO_KEY_IGNORE_PARITY) &&
		    ((key_info->algorithm == FSL_KEY_ALG_DES) ||
		     (key_info->algorithm == FSL_KEY_ALG_TDES))) {
			header ^= sah_insert_skha_no_key_parity;
		}

		/* Header by default is decrypting, so... */
		if (encrypt == SYM_ENCRYPT) {
			header ^= sah_insert_skha_encrypt;
		}

		if (sym_ctx->mode == FSL_SYM_MODE_CTR) {
			header ^= sah_insert_skha_modulus[sym_ctx->modulus_exp];
		}

		if (sym_ctx->mode == FSL_SYM_MODE_ECB) {
			ptr1 = NULL;
			size1 = 0;
		} else if (sym_ctx->flags & FSL_SYM_CTX_INIT) {
			ptr1 = (uint8_t *) block_zeros;
		} else {
			ptr1 = sym_ctx->context;
		}

		DESC_IN_KEY(header, sym_ctx->block_size_bytes, ptr1, key_info);

		/* Add in-out data descriptor */
		if (length != 0) {
			header = SAH_HDR_SKHA_ENC_DEC;
			if (LENGTH_PATCH && (sym_ctx->mode == FSL_SYM_MODE_CTR)
			    && ((length & LENGTH_PATCH_MASK) != 0)) {
				sink = DESC_TEMP_ALLOC(LENGTH_PATCH);
				ret =
				    sah_Create_Link(user_ctx->mem_util, &link1,
						    (uint8_t *) in, length,
						    SAH_USES_LINK_DATA);
				ret =
				    sah_Append_Link(user_ctx->mem_util, link1,
						    (uint8_t *) sink,
						    LENGTH_PATCH -
						    (length &
						     LENGTH_PATCH_MASK),
						    SAH_USES_LINK_DATA);
				if (ret != FSL_RETURN_OK_S) {
					goto out;
				}
				ret =
				    sah_Create_Link(user_ctx->mem_util, &link2,
						    out, length,
						    SAH_USES_LINK_DATA |
						    SAH_OUTPUT_LINK);
				if (ret != FSL_RETURN_OK_S) {
					goto out;
				}
				ret = sah_Append_Link(user_ctx->mem_util, link2,
						      sink,
						      LENGTH_PATCH -
						      (length &
						       LENGTH_PATCH_MASK),
						      SAH_USES_LINK_DATA);
				if (ret != FSL_RETURN_OK_S) {
					goto out;
				}
				ret =
				    sah_Append_Desc(user_ctx->mem_util,
						    &desc_chain, header, link1,
						    link2);
				if (ret != FSL_RETURN_OK_S) {
					goto out;
				}
				link1 = link2 = NULL;
			} else {
				DESC_IN_OUT(header, length, in, length, out);
			}
		}

		/* Unload any desired context */
		if (sym_ctx->flags & FSL_SYM_CTX_SAVE) {
			DESC_OUT_OUT(SAH_HDR_SKHA_READ_CONTEXT_IV, 0, NULL,
				     sym_ctx->block_size_bytes,
				     sym_ctx->context);
		}

	}			/* not ARC4 */

	SAH_SF_EXECUTE();

      out:
	SAH_SF_DESC_CLEAN();
	DESC_TEMP_FREE(sink);
	if (LENGTH_PATCH) {
		sah_Destroy_Link(user_ctx->mem_util, link1);
		sah_Destroy_Link(user_ctx->mem_util, link2);
	}

	return ret;
}