Beispiel #1
0
/**
This function verifies the DAA public key of a DAA Issuer with respect to its associated proof.
This is a resource consuming task. It can be done by trusted third party (certification).
This is an optional function and does not require a TPM or a TCS.
Parameters:
	- hDAA: Handle of the DAA object
	- issuerPk: DAA Issuer public key
	- issuerPkProof: Proofs the correctness of the DAA Issuer public key
	- isCorrect: Proofs the correctness of the DAA Issuer public key
*/
TSPICALL
Tspi_DAA_IssuerKeyVerification(TSS_HDAA          hDAA,		// in
			       TSS_HDAA_DATA     issuerPk,	// in (TSS_DAA_PK)
			       TSS_HDAA_DATA     issuerPkProof,	// in (TSS_DAA_PK_PROOF)
			       TSS_BOOL*         isCorrect)	// out
{
	TSS_RESULT result;
	int is_correct;
#ifdef TSS_DEBUG
	int before = mallinfo().uordblks;
#endif

	LogDebug("TSPI_DAA_IssuerKeyVerification hDAA=%ld issuerPk=%ld issuerPkProof=%ld",
		(long)hDAA, (long)issuerPk, (long)issuerPkProof);
	TSS_DAA_PK_internal *pk_internal = e_2_i_TSS_DAA_PK( (TSS_DAA_PK *)issuerPk);
	TSS_DAA_PK_PROOF_internal *proof_internal = e_2_i_TSS_DAA_PK_PROOF( issuerPkProof);
	LogDebug( "challenge=[%s]", dump_byte_array( proof_internal->length_challenge,
							proof_internal->challenge));
	result = is_pk_correct( pk_internal, proof_internal, &is_correct );
	if( is_correct) *isCorrect = TRUE;
	else *isCorrect = FALSE;
	bi_flush_memory();
#ifdef TSS_DEBUG
	LogDebug("TSPI_DAA_IssuerKeyVerification ALLOC DELTA:%d", mallinfo().uordblks-before);
#endif
	return result;
}
void update( EVP_MD_CTX *mdctx, char *name, bi_ptr integer, int bitLength) {
	int length = bitLength / 8;
	BYTE buffer[length];

	bi_2_byte_array( buffer, length, integer);
	LogDebug("[update] %s:%s", name, dump_byte_array( length, buffer));
	EVP_DigestUpdate(mdctx, buffer, length);
}
Beispiel #3
0
/*
 * Try using the PICC (the tag/card) with the given key to access block 0.
 * On success, it will show the key details, and dump the block data on Serial.
 *
 * @return true when the given key worked, false otherwise.
 */
bool try_key(MFRC522_MIFARE_Key *key) {
    bool result = false;
    uint8_t buffer[18];
    uint8_t block = 0;
    MFRC522_StatusCode status;

    // http://arduino.stackexchange.com/a/14316
  //  if (!MFRC522_PICC_IsNewCardPresent()) {
  //      return FALSE;
  //  }
  //  if (!MFRC522_PICC_ReadCardSerial()) {
  //      return FALSE;
  //  }
    CLS1_SendStr("Authenticating using key A...\r\n", CLS1_GetStdio()->stdOut);
    status = MFRC522_PCD_Authenticate(MFRC522_PICC_CMD_MF_AUTH_KEY_A, block, key, MFRC522_GetUid());
    if (status != STATUS_OK) {
      CLS1_SendStr("PCD_Authenticate() failed: ", CLS1_GetStdio()->stdErr);
      CLS1_SendStr(MFRC522_GetStatusCodeName(status), CLS1_GetStdio()->stdErr);
      CLS1_SendStr("\r\n", CLS1_GetStdio()->stdErr);
      return false;
    }
    // Read block
    uint8_t byteCount = sizeof(buffer);
    status = MFRC522_MIFARE_Read(block, buffer, &byteCount);
    if (status != STATUS_OK) {
      CLS1_SendStr("MIFARE_Read() failed: ", CLS1_GetStdio()->stdErr);
      CLS1_SendStr(MFRC522_GetStatusCodeName(status), CLS1_GetStdio()->stdErr);
    } else {
        // Successful read
        result = true;
        CLS1_SendStr("Success with key:", CLS1_GetStdio()->stdOut);
        dump_byte_array((*key).keyByte, MF_KEY_SIZE, TRUE);
        CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
        // Dump block data
        CLS1_SendStr("Block ", CLS1_GetStdio()->stdOut);
        CLS1_SendNum8u(block, CLS1_GetStdio()->stdOut);
        CLS1_SendStr(":", CLS1_GetStdio()->stdOut);
        dump_byte_array(buffer, 16, TRUE);
        CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
    }
    CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
    MFRC522_PICC_HaltA();       // Halt PICC
    MFRC522_PCD_StopCrypto1();  // Stop encryption on PCD
    return result;
}
Beispiel #4
0
void setup(void)
{
	SPI.begin();        // Init SPI bus
	mfrc522.PCD_Init(); // Init MFRC522 card
	
	// Prepare the key (used both as key A and as key B)
	// using FFFFFFFFFFFFh which is the default at chip delivery from the factory
	for (byte i = 0; i < 6; i++) {
		key.keyByte[i] = 0xFF;
	}
	
	Serial.println(F("Scan a MIFARE Classic PICC to demonstrate read and write."));
	Serial.print(F("Using key (for A and B):"));
	dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE);
	Serial.println();
	
	Serial.println(F("BEWARE: Data will be written to the PICC, in sector #1"));
}
Beispiel #5
0
int main(int argc, char *argv[]) {
	TSS_HCONTEXT hContext;
	TSS_RESULT result;
	TSS_HTPM hTPM;
	TSS_HPOLICY hPolicy;
	char *credential_filename = DEFAULT_CREDENTIAL_FILENAME;
	UINT32 nonceVerifierLength;
	BYTE *nonceVerifier;
	TSS_HDAA hDAA;
	TSS_DAA_CREDENTIAL *hDaaCredential;
	TSS_DAA_SIGN_DATA signData;
	TSS_DAA_SIGNATURE daaSignature;
	TSS_DAA_SELECTED_ATTRIB revealAttributes;
	char *szTpmPasswd = DEFAULT_OWN_PASSWD;
	char *message = NULL;
	BYTE **attributes = NULL;
	FILE *file;
	char *param;
	int i, length, rv;
	bi_ptr random = NULL;
	TSS_BOOL isCorrect;
	EVP_MD_CTX *mdctx;
	TSS_HKEY hKEY;

	init_tss_version( &signData);
	init_tss_version( &daaSignature);
	init_tss_version( &revealAttributes);
	i = 1;
	while( i < argc) {
		param = argv[ i];
		if ( strcmp( param, "-m") == 0 || strcmp( param, "--message") == 0) {
			i++;
			if( i == argc) return print_usage( argv[0]);
			message = argv[i];
		} else if( strcmp( param, "-cr") == 0 || strcmp( param, "--credential") == 0){
			i++;
			if( i == argc) return print_usage( argv[0]);
			credential_filename = argv[i];
		} else if( strcmp( param, "-pw") == 0 || strcmp( param, "--passwd") == 0){
			i++;
			if( i == argc) return print_usage( argv[0]);
			szTpmPasswd = argv[i];
		} else {
			fprintf(stderr, "%s:unrecognized option `%s'\n", argv[0], param);
			return print_usage( argv[0]);
		}
		i++;
	}
	bi_init( NULL);
	printf("Loading credential: %s ", credential_filename);
	file = fopen( credential_filename, "r");
	if( (hDaaCredential = load_TSS_DAA_CREDENTIAL( file)) == 0) {
		LogError( "[test_join]: Error when loading \'%s\': %s\n",
			credential_filename,
			strerror( errno));
		result = TSS_E_FAIL;
		goto out_close;
	}
	fclose( file);
	printf("Done\n");

	// Create Context
	LogDebug("Create Context");
	result = Tspi_Context_Create( &hContext );
	if ( result != TSS_SUCCESS )
	{
		LogError( "Tspi_Context_Create %d\n", result );
		goto out;
	}
	// Connect to Context
	result = Tspi_Context_Connect( hContext, NULL );
	if ( result != TSS_SUCCESS) goto out_close;
	printf("\nConnect to the context: %X\n", hContext);

	if( (result = Tspi_Context_GetTpmObject( hContext, &hTPM)) != TSS_SUCCESS)
		goto out_close;
	// Get the correct policy using the TPM ownership PASSWD
	if( (result = Tspi_GetPolicyObject( hTPM, TSS_POLICY_USAGE, &hPolicy)) != TSS_SUCCESS)
		goto out_close;
	if( (result = Tspi_Policy_SetSecret( hPolicy,
						TSS_SECRET_MODE_PLAIN,
						strlen( szTpmPasswd),
						szTpmPasswd)) != TSS_SUCCESS)
		goto out_close;
	LogDebug("Tspi_Policy_SetSecret hPolicy received;%d", hPolicy);

	//Create Object
	result = obj_daa_add( hContext, &hDAA);
	if (result != TSS_SUCCESS) {
		LogError("Tspi_Context_CreateObject:%d", result);
		Tspi_Context_Close(hContext);
		LogError("%s: %s", argv[0], err_string(result));
		exit(result);
	}
	LogDebug("created DAA object:%X", hDAA);

	// TODO: verifier base name ??
	result = Tspi_DAA_VerifyInit(
		hDAA,	// in
		&nonceVerifierLength,	// out
		&nonceVerifier,	// out
		0, //baseNameLength,	// out
		NULL //baseName		// out
	);
	if (result != TSS_SUCCESS) goto out_close;
	LogDebug("Verify Init return nonceVerifier [%s]",
			dump_byte_array( nonceVerifierLength, nonceVerifier));

	create_TSS_DAA_SELECTED_ATTRIB( &revealAttributes, 5, 0, 1, 1, 0, 0);

	mdctx = EVP_MD_CTX_create();

	// create the TSS_DAA_SIGN_DATA struct
	// .selector: 0 -> payload contains a handle to an AIK
	//            1 -> payload contains a hashed message
	if( message != NULL) {
		signData.selector = TSS_FLAG_DAA_SIGN_MESSAGE_HASH;
		signData.payloadFlag = TSS_FLAG_DAA_SIGN_MESSAGE_HASH;
		EVP_DigestInit(mdctx, DAA_PARAM_get_message_digest());
		EVP_DigestUpdate(mdctx,  (BYTE *)message, strlen( message));
		signData.payloadLength = EVP_MD_CTX_size(mdctx);
		signData.payload = (BYTE *)EVP_MD_CTX_create();
		EVP_DigestFinal(mdctx, signData.payload, NULL);
	} else {
		signData.selector = TSS_FLAG_DAA_SIGN_IDENTITY_KEY;
		result = Tspi_Context_CreateObject(
			hContext,	 //  in
			TSS_OBJECT_TYPE_RSAKEY,		//  in
			TSS_KEY_SIZE_2048,		//  in
			&hKEY	//  out
		);
		if( result != TSS_SUCCESS) goto out_close;

	}

	result = Tspi_TPM_DAA_Sign(
		hDAA,	// in
		hTPM,	// in
		(TSS_HKEY)hDaaCredential,	// in
		revealAttributes,	// in
		0, // verifierBaseNameLength,	// in
		NULL, // verifierBaseName,	// in
		nonceVerifierLength,	// in
		nonceVerifier,	// in
		signData,	// in
		&daaSignature	// out
	);
	if (result != TSS_SUCCESS) goto out_close;
	LogDebug("TPM_DAA_Sign return daaSignature [%s]",
			dump_byte_array( nonceVerifierLength, nonceVerifier));

	// generate attributes list but without copying the not revealed ones
	attributes = malloc( sizeof(BYTE *) * hDaaCredential->attributesLength);
	for( i=0; i < (int)(hDaaCredential->attributesLength); i++) {
		if( revealAttributes.indicesList[i]) {
			attributes[i] = (BYTE *)malloc( DAA_PARAM_SIZE_F_I / 8);
			memcpy( attributes[i],
				hDaaCredential->attributes[i],
				DAA_PARAM_SIZE_F_I / 8);
		} else {
			attributes[i] = NULL;
		}
	}

	result = Tspi_DAA_VerifySignature(
		hDAA,	// in
		daaSignature,	// in
		(TSS_HKEY)&(hDaaCredential->issuerPK),	// in
		signData,	// in
		hDaaCredential->attributesLength,	// in
		attributes,	// in
		nonceVerifierLength,	// in
		nonceVerifier,	// in
		0,	//baseNameLength,	//in
		NULL,	// in
		&isCorrect	// out
	);
	printf("Signature correct:%s\n", ( isCorrect ? "yes" : "no"));

out_close:
	EVP_MD_CTX_destroy(mdctx);
	if( attributes != NULL) {
		for( i=0; i<(int)hDaaCredential->attributesLength; i++) {
			if( attributes[i] != NULL) free( attributes[i]);
		}
		free( attributes);
	}
	if( random != NULL) bi_free_ptr( random);
	Tspi_Context_FreeMemory( hContext, NULL );
	Tspi_Context_Close( hContext );
out:
	bi_release();
	LogDebug("THE END result=%d:%s",result, err_string( result) );;
	return result;
}
Beispiel #6
0
void loop() {
	// Look for new cards
	if ( ! mfrc522.PICC_IsNewCardPresent())
		return;
	
	// Select one of the cards
	if ( ! mfrc522.PICC_ReadCardSerial())
		return;
	
	// Show some details of the PICC (that is: the tag/card)
	Serial.print(F("Card UID:"));
	dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
	Serial.println();
	Serial.print(F("PICC type: "));
	byte piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
	Serial.println(mfrc522.PICC_GetTypeName(piccType));
	
	// Check for compatibility
	if (    piccType != MFRC522::PICC_TYPE_MIFARE_MINI
		&&  piccType != MFRC522::PICC_TYPE_MIFARE_1K
		&&  piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
		Serial.println(F("This sample only works with MIFARE Classic cards."));
		return;
	}
	
	// In this sample we use the second sector,
	// that is: sector #1, covering block #4 up to and including block #7
	byte sector         = 1;
	byte blockAddr      = 4;
	byte dataBlock[]    = {
		0x01, 0x02, 0x03, 0x04, //  1,  2,   3,  4,
		0x05, 0x06, 0x07, 0x08, //  5,  6,   7,  8,
		0x08, 0x09, 0xff, 0x0b, //  9, 10, 255, 12,
		0x0c, 0x0d, 0x0e, 0x0f  // 13, 14,  15, 16
	};
	byte trailerBlock   = 7;
	byte status;
	byte buffer[18];
	byte size = sizeof(buffer);
	
	// Authenticate using key A
	Serial.println(F("Authenticating using key A..."));
	status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
	if (status != MFRC522::STATUS_OK) {
		Serial.print(F("PCD_Authenticate() failed: "));
		Serial.println(mfrc522.GetStatusCodeName(status));
		return;
	}
	
	// Show the whole sector as it currently is
	Serial.println(F("Current data in sector:"));
	mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
	Serial.println();
	
	// Read data from the block
	Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
	Serial.println(F(" ..."));
	status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
	if (status != MFRC522::STATUS_OK) {
		Serial.print(F("MIFARE_Read() failed: "));
		Serial.println(mfrc522.GetStatusCodeName(status));
	}
	Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
	dump_byte_array(buffer, 16); Serial.println();
	Serial.println();
	
	// Authenticate using key B
	Serial.println(F("Authenticating again using key B..."));
	status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, &(mfrc522.uid));
	if (status != MFRC522::STATUS_OK) {
		Serial.print(F("PCD_Authenticate() failed: "));
		Serial.println(mfrc522.GetStatusCodeName(status));
		return;
	}
	
	// Write data to the block
	Serial.print(F("Writing data into block ")); Serial.print(blockAddr);
	Serial.println(F(" ..."));
	dump_byte_array(dataBlock, 16); Serial.println();
	status = mfrc522.MIFARE_Write(blockAddr, dataBlock, 16);
	if (status != MFRC522::STATUS_OK) {
		Serial.print(F("MIFARE_Write() failed: "));
		Serial.println(mfrc522.GetStatusCodeName(status));
	}
	Serial.println();
	
	// Read data from the block (again, should now be what we have written)
	Serial.print(F("Reading data from block ")); Serial.print(blockAddr);
	Serial.println(F(" ..."));
	status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
	if (status != MFRC522::STATUS_OK) {
		Serial.print(F("MIFARE_Read() failed: "));
		Serial.println(mfrc522.GetStatusCodeName(status));
	}
	Serial.print(F("Data in block ")); Serial.print(blockAddr); Serial.println(F(":"));
	dump_byte_array(buffer, 16); Serial.println();
	
	// Check that data in block is what we have written
	// by counting the number of bytes that are equal
	Serial.println(F("Checking result..."));
	byte count = 0;
	for (byte i = 0; i < 16; i++) {
		// Compare buffer (= what we've read) with dataBlock (= what we've written)
		if (buffer[i] == dataBlock[i])
			count++;
	}
	Serial.print(F("Number of bytes that match = ")); Serial.println(count);
	if (count == 16) {
		Serial.println(F("Success :-)"));
	} else {
		Serial.println(F("Failure, no match :-("));
		Serial.println(F("  perhaps the write didn't work properly..."));
	}
	Serial.println();
	
	// Dump the sector data
	Serial.println(F("Current data in sector:"));
	mfrc522.PICC_DumpMifareClassicSectorToSerial(&(mfrc522.uid), &key, sector);
	Serial.println();
	
	// Halt PICC
	mfrc522.PICC_HaltA();
	// Stop encryption on PCD
	mfrc522.PCD_StopCrypto1();
}
BYTE *compute_sign_challenge_host(
	int *result_length,
	EVP_MD *digest,
	TSS_DAA_PK_internal *issuer_pk,
	int nonce_verifierLength,
	BYTE *nonce_verifier,
	int selected_attributes2commitLength,
	TSS_DAA_SELECTED_ATTRIB **selected_attributes2commit,
	int is_anonymity_revocation_enabled,
	bi_ptr zeta,
	bi_ptr capital_t,
	bi_ptr capital_tilde,
	int attribute_commitmentsLength,
	TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitments,
	TSS_DAA_ATTRIB_COMMIT_internal **attribute_commitment_proofs,
	bi_ptr capital_nv,
	bi_ptr capital_tilde_v,
	CS_PUBLIC_KEY *anonymity_revocator_pk,
	CS_ENCRYPTION_RESULT *encryption_result_rand,
	CS_ENCRYPTION_RESULT *encryption_result_proof
) {
	EVP_MD_CTX mdctx;
	int i, length;
	unsigned int big_indian;
	BYTE *buffer;
	int length_gamma_modulus;
	BYTE *buffer1;

	LogDebug("issuer_pk basename[%d]:%s",
		issuer_pk->issuerBaseNameLength,
		dump_byte_array( issuer_pk->issuerBaseNameLength,
				issuer_pk->issuerBaseName));
	LogDebug("nonce_verifier[%d]:%s",
		nonce_verifierLength,
		dump_byte_array( nonce_verifierLength, nonce_verifier));
	LogDebug("selected_attributes2commitLength:%d", selected_attributes2commitLength);
	LogDebug("is_anonymity_revocation_enabled:%d", is_anonymity_revocation_enabled);
	LogDebug("zeta[%ld]:%s", bi_nbin_size( zeta), bi_2_hex_char( zeta));
	LogDebug("capital_t[%ld]:%s", bi_nbin_size( capital_t), bi_2_hex_char( capital_t));
	LogDebug("capital_tilde[%ld]:%s",
		bi_nbin_size( capital_tilde),
		bi_2_hex_char( capital_tilde));
	LogDebug("attribute_commitmentsLength:%d", attribute_commitmentsLength);
	LogDebug("attribute_commitments:%d", (int)attribute_commitments);
	LogDebug("attribute_commitment_proofs:%d", (int)attribute_commitment_proofs);
	LogDebug("capital_nv[%ld]:%s", bi_nbin_size( capital_nv), bi_2_hex_char( capital_nv));
	LogDebug("capital_tilde_v[%ld]:%s",
		bi_nbin_size( capital_tilde_v),
		bi_2_hex_char( capital_tilde_v));
	LogDebug("anonymity_revocator_pk:%d", (int)anonymity_revocator_pk);
	LogDebug("encryption_result_rand:%d", (int)encryption_result_rand);
	LogDebug("encryption_result_proof:%d", (int)encryption_result_proof);

	EVP_MD_CTX_init(&mdctx);
	EVP_DigestInit_ex(&mdctx, digest, NULL);
	// update with encoded PK
	buffer = encoded_DAA_PK_internal( &length, issuer_pk);
	if( buffer == NULL) return NULL;
	LogDebug("encoded issuer_pk[%d]:%s", length, dump_byte_array( length, buffer));
	EVP_DigestUpdate(&mdctx, buffer , length);
	free( buffer);
	// nonce verifier
	EVP_DigestUpdate(&mdctx, nonce_verifier , nonce_verifierLength);
	// length Commitments
	big_indian = attribute_commitmentsLength;
	EVP_DigestUpdate(&mdctx, &big_indian, sizeof(int));
	// Anonymity enabled
	big_indian = is_anonymity_revocation_enabled;
	EVP_DigestUpdate(&mdctx, &big_indian, sizeof(int));

	update( &mdctx, "zeta", zeta, DAA_PARAM_SIZE_MODULUS_GAMMA);
	update( &mdctx, "capitalT", capital_t, DAA_PARAM_SIZE_RSA_MODULUS);
	update( &mdctx, "capitalTTilde", capital_tilde, DAA_PARAM_SIZE_RSA_MODULUS);

	length_gamma_modulus = DAA_PARAM_SIZE_MODULUS_GAMMA / 8;
	buffer = (BYTE *)malloc( length_gamma_modulus);// allocation
	if (buffer == NULL) {
		LogError("malloc of %d bytes failed", length_gamma_modulus);
		return NULL;
	}
	if( selected_attributes2commitLength > 0) {
		for( i=0; i<selected_attributes2commitLength; i++) {
			buffer1 = to_bytes_TSS_DAA_SELECTED_ATTRIB_internal(
				&length,
				selected_attributes2commit[i]);
			EVP_DigestUpdate(&mdctx, buffer1, length);
			free( buffer1);
			bi_2_byte_array( buffer,
					length_gamma_modulus,
					attribute_commitments[i]->beta);
			EVP_DigestUpdate(&mdctx,
					buffer,
					length_gamma_modulus);
			bi_2_byte_array( buffer,
					length_gamma_modulus,
					attribute_commitment_proofs[i]->beta);
			EVP_DigestUpdate(&mdctx,
					buffer,
					length_gamma_modulus);
		}
	}
	if( !is_anonymity_revocation_enabled) {
		// Nv, N~v
		bi_2_byte_array( buffer, length_gamma_modulus, capital_nv);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, capital_tilde_v);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
	} else {
		bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->eta);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda1);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda2);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, anonymity_revocator_pk->lambda3);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c1);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c2);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c3);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_rand->c4);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c1);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c2);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c3);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
		bi_2_byte_array( buffer, length_gamma_modulus, encryption_result_proof->c4);
		EVP_DigestUpdate(&mdctx, buffer, length_gamma_modulus);
	}
	free(buffer);
	buffer = (BYTE *)malloc(EVP_MD_size(digest)); // allocation
	if (buffer == NULL) {
		LogError("malloc of %d bytes failed", EVP_MD_size(digest));
		return NULL;
	}
	EVP_DigestFinal_ex(&mdctx, buffer, result_length);
	EVP_MD_CTX_cleanup(&mdctx);
	LogDebug("compute_sign_challenge_host[%d]:%s",
		*result_length,
		dump_byte_array( *result_length, buffer));
	return buffer;
}
int map_aead_request(struct device *dev, struct aead_request *req)
{
	struct aead_req_ctx *areq_ctx = aead_request_ctx(req);
	unsigned int hw_iv_size = areq_ctx->hw_iv_size;
	struct mlli_params *mlli_params = &areq_ctx->mlli_params;
	struct sg_data_array sg_data;
	unsigned int authsize = areq_ctx->req_authsize;
	unsigned int size_for_map;
	struct buff_mgr_handle *buff_mgr = crypto_drvdata->buff_mgr_handle;
	int dummy = 0; /*used for the assoc data fragments */
	int src_last_bytes = 0;
	int dst_last_bytes = 0;
	int rc = -ENOMEM;

	areq_ctx->assoc_dma_buf_type = DX_DMA_BUF_NULL;
	areq_ctx->data_dma_buf_type = DX_DMA_BUF_DLLI;
	mlli_params->curr_pool = NULL;
	areq_ctx->out_nents = 0;
	areq_ctx->is_icv_frag = false;
	sg_data.num_of_sg = 0;

	/* cacluate the size for cipher remove ICV in decrypt*/
	areq_ctx->cryptlen = (areq_ctx->gen_ctx.op_type ==
				 SEP_CRYPTO_DIRECTION_ENCRYPT) ?
				req->cryptlen :
				(req->cryptlen - authsize);

	areq_ctx->mac_buf_dma_addr = dma_map_single(dev,
		areq_ctx->mac_buf, MAX_MAC_SIZE, DMA_BIDIRECTIONAL);
	if (unlikely(dma_mapping_error(dev, areq_ctx->mac_buf_dma_addr))) {
		DX_LOG_ERR("Mapping mac_buf %u B at va=0x%08lX "
			"for DMA failed\n", MAX_MAC_SIZE,
			(unsigned long)areq_ctx->mac_buf);
		goto aead_map_failure;
	}

	if (likely(req->iv)) {
		dump_byte_array("iv", (uint8_t *)req->iv, hw_iv_size);
		areq_ctx->gen_ctx.iv_dma_addr = dma_map_single(dev,
			req->iv, hw_iv_size, DMA_BIDIRECTIONAL);
		if (unlikely(dma_mapping_error(
			dev, areq_ctx->gen_ctx.iv_dma_addr))) {
			DX_LOG_ERR("Mapping iv %u B at va=0x%08lX "
				   "for DMA failed\n",hw_iv_size,
				     (unsigned long)req->iv);
			goto aead_map_failure;
		}
		DX_LOG_DEBUG("Mapped iv %u B at va=0x%08lX to dma=0x%08lX\n",
			hw_iv_size, (unsigned long)req->iv,
			(unsigned long)areq_ctx->gen_ctx.iv_dma_addr);
	} else {
		areq_ctx->gen_ctx.iv_dma_addr = 0;
	}

	if (areq_ctx->ccm_hdr_size != ccm_header_size_null) {
		areq_ctx->ccm_iv0_dma_addr = dma_map_single(dev,
			(areq_ctx->ccm_config + CCM_CTR_COUNT_0_OFFSET),
			AES_BLOCK_SIZE, DMA_TO_DEVICE);

		if (unlikely(dma_mapping_error(dev, areq_ctx->ccm_iv0_dma_addr))) {
			DX_LOG_ERR("Mapping mac_buf %u B at va=0x%08lX "
			"for DMA failed\n", AES_BLOCK_SIZE, (unsigned long)
			(areq_ctx->ccm_config + CCM_CTR_COUNT_0_OFFSET));
			areq_ctx->ccm_iv0_dma_addr = 0;
			goto aead_map_failure;
		}
		if (dx_aead_handle_config_buf(dev, areq_ctx,
					      areq_ctx->ccm_config,
					      &sg_data,req->assoclen)){
			goto aead_map_failure;
		}
	}

	/*associated data*/
	if (req->assoclen != 0 ) {
		if (unlikely( dx_map_sg(dev, req->assoc,
					 req->assoclen,
					 DMA_TO_DEVICE,
					 &areq_ctx->assoc_nents,
					 LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES,
					 &dummy))) {
			goto aead_map_failure;
		}
		/*in CCM case we have additional entry for ccm header configurations */
		if (areq_ctx->ccm_hdr_size != ccm_header_size_null) {
			if (unlikely((areq_ctx->assoc_nents + 1) >
				LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES)) {
				DX_LOG_ERR("CCM case.Too many fragments. "
					   "Current %d max %d\n",
				(areq_ctx->assoc_nents + 1),
				LLI_MAX_NUM_OF_ASSOC_DATA_ENTRIES);
				goto aead_map_failure;
			}
		}

		if (likely(areq_ctx->assoc_nents == 1) &&
		    (areq_ctx->ccm_hdr_size == ccm_header_size_null)) {
			areq_ctx->assoc_dma_buf_type = DX_DMA_BUF_DLLI;
		} else {
			areq_ctx->assoc_dma_buf_type = DX_DMA_BUF_MLLI;
			buffer_mgr_set_sg_entry(&sg_data,
						areq_ctx->assoc_nents,
						req->assoc,
						req->assoclen,
						true);
			DX_LOG_DEBUG("Non-contig. assoc: buf type = %s "
				"assoc_nents 0x%08lX \n",
				dx_get_buff_type(areq_ctx->assoc_dma_buf_type),
				(long unsigned int)(areq_ctx->assoc_nents));
		}
	} else {
		areq_ctx->assoc_dma_buf_type = DX_DMA_BUF_NULL;
	}

	if (likely(req->src == req->dst)) {
		size_for_map = (areq_ctx->gen_ctx.op_type ==
				SEP_CRYPTO_DIRECTION_ENCRYPT) ?
				(req->cryptlen + authsize) :
				(req->cryptlen);
	} else {
		/* in case of non-inplace the
		source len is alway cryptlen */
		size_for_map = req->cryptlen;
	}

	if (unlikely(dx_map_sg(dev, req->src, size_for_map,
		DMA_BIDIRECTIONAL, &areq_ctx->in_nents,
		LLI_MAX_NUM_OF_DATA_ENTRIES, &src_last_bytes)))
		goto aead_map_failure;

	if (areq_ctx->in_nents > 1)
		areq_ctx->data_dma_buf_type = DX_DMA_BUF_MLLI;

	if (likely(req->src == req->dst)) {
		if (unlikely(areq_ctx->data_dma_buf_type == DX_DMA_BUF_MLLI)) {
			areq_ctx->out_nents = 0;
			buffer_mgr_set_sg_entry(&sg_data,
						areq_ctx->in_nents,
						req->src,
						areq_ctx->cryptlen,
						true);
		}
	} else {
		/* non inplace operation,
		calculate the size for dst buffer */
		size_for_map = (areq_ctx->gen_ctx.op_type ==
				SEP_CRYPTO_DIRECTION_ENCRYPT) ?
				(req->cryptlen + authsize) :
				(req->cryptlen - authsize);
		if (unlikely(dx_map_sg(dev, req->dst, size_for_map,
					 DMA_BIDIRECTIONAL,
					 &areq_ctx->out_nents,
					 LLI_MAX_NUM_OF_DATA_ENTRIES,
					 &dst_last_bytes))) {
			goto aead_map_failure;
		}

		if (areq_ctx->out_nents > 1)
			areq_ctx->data_dma_buf_type = DX_DMA_BUF_MLLI;

		if (unlikely(areq_ctx->data_dma_buf_type == DX_DMA_BUF_MLLI)) {
			buffer_mgr_set_sg_entry(&sg_data,
						areq_ctx->in_nents,
						req->src,
						areq_ctx->cryptlen,
						true);
			buffer_mgr_set_sg_entry(&sg_data,
						areq_ctx->out_nents,
						req->dst,
						areq_ctx->cryptlen,
						true);
		}
	}

	/*ICV handling */
	if ((areq_ctx->out_nents == 0) ||
	    (areq_ctx->gen_ctx.op_type == SEP_CRYPTO_DIRECTION_DECRYPT))  {
		if (likely(src_last_bytes >= authsize)) {
			if (likely(src_last_bytes != authsize))
				areq_ctx->icv_only_frag = 0;
			else
				/*The ICV is not fragmented but place
				in the last sg enrtry without data */
				areq_ctx->icv_only_frag = 1;

			areq_ctx->icv_sg = &req->src[areq_ctx->in_nents - 1];
			areq_ctx->icv_offset = src_last_bytes - authsize;
		} else {
			rc = dx_aead_handle_frag_icv(dev, req, src_last_bytes);
			if (rc != 0)
				goto aead_map_failure;
		}
	} else {
		areq_ctx->icv_only_frag = 0;
		if (likely(dst_last_bytes >= authsize)) {
			areq_ctx->icv_sg = &req->dst[areq_ctx->out_nents - 1];
			areq_ctx->icv_offset = dst_last_bytes - authsize;
		} else {
			rc = dx_aead_handle_frag_icv(dev, req, dst_last_bytes);
			if (rc != 0)
				goto aead_map_failure;
		}
	}

	/* Mlli support - start building the MLLI according to
	   the above results*/
	if ((unlikely(areq_ctx->data_dma_buf_type == DX_DMA_BUF_MLLI) ||
	    (areq_ctx->assoc_dma_buf_type == DX_DMA_BUF_MLLI))) {
		mlli_params->curr_pool = buff_mgr->mlli_buffs_pool;
		/*only if one of the pools was set there is MLLI operation*/
		if (unlikely(buffer_mgr_build_mlli(dev, &sg_data,
						  mlli_params))) {
			goto aead_map_failure;
		}
	}

	return 0;

aead_map_failure:
	unmap_aead_request(dev, req);
	return rc;
}
int map_ablkcipher_request(struct device *dev, struct ablkcipher_request *req)
{
	struct ablkcipher_req_ctx *areq_ctx = ablkcipher_request_ctx(req);
	unsigned int iv_size = crypto_ablkcipher_ivsize(crypto_ablkcipher_reqtfm(req));
	struct mlli_params *mlli_params = &areq_ctx->mlli_params;
	struct sg_data_array sg_data;
	struct buff_mgr_handle *buff_mgr = crypto_drvdata->buff_mgr_handle;
	int dummy = 0;
	int rc = 0;

	areq_ctx->sec_dir = 0;
	areq_ctx->dma_buf_type = DX_DMA_BUF_DLLI;
	mlli_params->curr_pool = NULL;
	sg_data.num_of_sg = 0;

	/* Map IV buffer */
	if (likely(iv_size != 0) ) {
		dump_byte_array("iv", (uint8_t *)req->info, iv_size);
		areq_ctx->gen_ctx.iv_dma_addr =
			dma_map_single(dev, (void *)req->info,
				       iv_size, DMA_TO_DEVICE);
		if (unlikely(dma_mapping_error(dev,
					areq_ctx->gen_ctx.iv_dma_addr))) {
			DX_LOG_ERR("Mapping iv %u B at va=0x%08lX "
				   "for DMA failed\n",iv_size,
				    (unsigned long)req->info);
			return -ENOMEM;
		}
		DX_LOG_DEBUG("Mapped iv %u B at va=0x%08lX to dma=0x%08lX\n",
				iv_size, (unsigned long)req->info,
			     (unsigned long)areq_ctx->gen_ctx.iv_dma_addr);
	} else {
		areq_ctx->gen_ctx.iv_dma_addr = 0;
	}

	/* Map the src sg */
	if ( sg_is_last(req->src) &&
	     (sg_page(req->src) == NULL) &&
	     sg_dma_address(req->src)) {
		/* The source is secure no mapping is needed */
		areq_ctx->sec_dir = DX_SRC_DMA_IS_SECURE;
		areq_ctx->in_nents = 1;
	} else {
		if ( unlikely( dx_map_sg( dev,req->src, req->nbytes,
					  DMA_BIDIRECTIONAL,
					  &areq_ctx->in_nents,
					  LLI_MAX_NUM_OF_DATA_ENTRIES,
					  &dummy))){
			rc = -ENOMEM;
			goto fail_unmap_iv;
		}

		if ( areq_ctx->in_nents > 1 ) {
			areq_ctx->dma_buf_type = DX_DMA_BUF_MLLI;
		}
	}

	if ( unlikely(req->src == req->dst)) {
		if ( areq_ctx->sec_dir == DX_SRC_DMA_IS_SECURE ) {
			DX_LOG_ERR("Secure key inplace operation "
				   "is not supported \n");
			/* both sides are secure */
			rc = -ENOMEM;
			goto fail_unmap_din;
		}
		/* Handle inplace operation */
		if ( unlikely(areq_ctx->dma_buf_type == DX_DMA_BUF_MLLI) ) {
			areq_ctx->out_nents = 0;
			buffer_mgr_set_sg_entry(&sg_data,
						areq_ctx->in_nents,
						req->src,
						req->nbytes,
						true);
		}
	} else {
		if ( sg_is_last(req->dst) &&
		     (sg_page(req->dst) == NULL) &&
		     sg_dma_address(req->dst)) {
			if ( areq_ctx->sec_dir == DX_SRC_DMA_IS_SECURE ) {
				DX_LOG_ERR("Secure key in both sides is"
					   "not supported \n");
				/* both sides are secure */
				rc = -ENOMEM;
				goto fail_unmap_din;
			}
			/* The dest is secure no mapping is needed */
			areq_ctx->sec_dir = DX_DST_DMA_IS_SECURE;
			areq_ctx->out_nents = 1;
		} else {
			/* Map the dst sg */
			if ( unlikely( dx_map_sg(dev,req->dst, req->nbytes,
						 DMA_BIDIRECTIONAL,
						 &areq_ctx->out_nents,
						 LLI_MAX_NUM_OF_DATA_ENTRIES,
						 &dummy))){
				rc = -ENOMEM;
				goto fail_unmap_din;
			}

			if ( areq_ctx->out_nents > 1 ) {
				areq_ctx->dma_buf_type = DX_DMA_BUF_MLLI;
			}
		}
		if ( unlikely( (areq_ctx->dma_buf_type == DX_DMA_BUF_MLLI) ) ) {
			if (areq_ctx->sec_dir != DX_SRC_DMA_IS_SECURE) {
				buffer_mgr_set_sg_entry(&sg_data,
							areq_ctx->in_nents,
							req->src,
							req->nbytes,
							true);
			}
			if (areq_ctx->sec_dir != DX_DST_DMA_IS_SECURE) {
				buffer_mgr_set_sg_entry(&sg_data,
							areq_ctx->out_nents,
							req->dst,
							req->nbytes,
							true);
			}
		} /*few entries */
	} /* !inplace */

	if (unlikely(areq_ctx->dma_buf_type == DX_DMA_BUF_MLLI)) {
#if (DX_DEV_SIGNATURE == DX_CC441P_SIG)
		if (areq_ctx->sec_dir) {
			/* one of the sides is secure, can't use MLLI*/
			rc = -EINVAL;
			goto fail_unmap_dout;
		}
#endif
		mlli_params->curr_pool = buff_mgr->mlli_buffs_pool;
		if (unlikely(buffer_mgr_build_mlli(dev, &sg_data, mlli_params))) {
			rc = -ENOMEM;
			goto fail_unmap_dout;
		}
	} /*MLLI case*/

	DX_LOG_DEBUG(" buf type = %s \n",
		     dx_get_buff_type(areq_ctx->dma_buf_type));
	return 0;
fail_unmap_dout:
	if (areq_ctx->sec_dir != DX_DST_DMA_IS_SECURE) {
		dma_unmap_sg(dev, req->dst,
			     areq_ctx->out_nents, DMA_BIDIRECTIONAL);
	}
fail_unmap_din:
	if (areq_ctx->sec_dir != DX_SRC_DMA_IS_SECURE) {
		dma_unmap_sg(dev, req->src,
			     areq_ctx->in_nents, DMA_BIDIRECTIONAL);
	}
fail_unmap_iv:
	if (areq_ctx->gen_ctx.iv_dma_addr != 0) {
		dma_unmap_single(dev, areq_ctx->gen_ctx.iv_dma_addr,
				 iv_size, DMA_TO_DEVICE);
	}
	return rc;
}
Beispiel #10
0
int cc_map_cipher_request(struct cc_drvdata *drvdata, void *ctx,
			  unsigned int ivsize, unsigned int nbytes,
			  void *info, struct scatterlist *src,
			  struct scatterlist *dst, gfp_t flags)
{
	struct cipher_req_ctx *req_ctx = (struct cipher_req_ctx *)ctx;
	struct mlli_params *mlli_params = &req_ctx->mlli_params;
	struct buff_mgr_handle *buff_mgr = drvdata->buff_mgr_handle;
	struct device *dev = drvdata_to_dev(drvdata);
	struct buffer_array sg_data;
	u32 dummy = 0;
	int rc = 0;
	u32 mapped_nents = 0;

	req_ctx->dma_buf_type = CC_DMA_BUF_DLLI;
	mlli_params->curr_pool = NULL;
	sg_data.num_of_buffers = 0;

	/* Map IV buffer */
	if (ivsize) {
		dump_byte_array("iv", (u8 *)info, ivsize);
		req_ctx->gen_ctx.iv_dma_addr =
			dma_map_single(dev, (void *)info,
				       ivsize, DMA_TO_DEVICE);
		if (dma_mapping_error(dev, req_ctx->gen_ctx.iv_dma_addr)) {
			dev_err(dev, "Mapping iv %u B at va=%pK for DMA failed\n",
				ivsize, info);
			return -ENOMEM;
		}
		dev_dbg(dev, "Mapped iv %u B at va=%pK to dma=%pad\n",
			ivsize, info, &req_ctx->gen_ctx.iv_dma_addr);
	} else {
		req_ctx->gen_ctx.iv_dma_addr = 0;
	}

	/* Map the src SGL */
	rc = cc_map_sg(dev, src, nbytes, DMA_BIDIRECTIONAL, &req_ctx->in_nents,
		       LLI_MAX_NUM_OF_DATA_ENTRIES, &dummy, &mapped_nents);
	if (rc)
		goto cipher_exit;
	if (mapped_nents > 1)
		req_ctx->dma_buf_type = CC_DMA_BUF_MLLI;

	if (src == dst) {
		/* Handle inplace operation */
		if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) {
			req_ctx->out_nents = 0;
			cc_add_sg_entry(dev, &sg_data, req_ctx->in_nents, src,
					nbytes, 0, true,
					&req_ctx->in_mlli_nents);
		}
	} else {
		/* Map the dst sg */
		rc = cc_map_sg(dev, dst, nbytes, DMA_BIDIRECTIONAL,
			       &req_ctx->out_nents, LLI_MAX_NUM_OF_DATA_ENTRIES,
			       &dummy, &mapped_nents);
		if (rc)
			goto cipher_exit;
		if (mapped_nents > 1)
			req_ctx->dma_buf_type = CC_DMA_BUF_MLLI;

		if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) {
			cc_add_sg_entry(dev, &sg_data, req_ctx->in_nents, src,
					nbytes, 0, true,
					&req_ctx->in_mlli_nents);
			cc_add_sg_entry(dev, &sg_data, req_ctx->out_nents, dst,
					nbytes, 0, true,
					&req_ctx->out_mlli_nents);
		}
	}

	if (req_ctx->dma_buf_type == CC_DMA_BUF_MLLI) {
		mlli_params->curr_pool = buff_mgr->mlli_buffs_pool;
		rc = cc_generate_mlli(dev, &sg_data, mlli_params, flags);
		if (rc)
			goto cipher_exit;
	}

	dev_dbg(dev, "areq_ctx->dma_buf_type = %s\n",
		cc_dma_buf_type(req_ctx->dma_buf_type));

	return 0;

cipher_exit:
	cc_unmap_cipher_request(dev, req_ctx, ivsize, src, dst);
	return rc;
}
Beispiel #11
0
static int cc_cipher_setkey(struct crypto_ablkcipher *atfm, const u8 *key,
			    unsigned int keylen)
{
	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(atfm);
	struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
	struct device *dev = drvdata_to_dev(ctx_p->drvdata);
	u32 tmp[DES_EXPKEY_WORDS];
	unsigned int max_key_buf_size = get_max_keysize(tfm);

	dev_dbg(dev, "Setting key in context @%p for %s. keylen=%u\n",
		ctx_p, crypto_tfm_alg_name(tfm), keylen);
	dump_byte_array("key", (u8 *)key, keylen);

	/* STAT_PHASE_0: Init and sanity checks */

	if (validate_keys_sizes(ctx_p, keylen)) {
		dev_err(dev, "Unsupported key size %d.\n", keylen);
		crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
		return -EINVAL;
	}

	if (cc_is_hw_key(tfm)) {
		/* setting HW key slots */
		struct arm_hw_key_info *hki = (struct arm_hw_key_info *)key;

		if (ctx_p->flow_mode != S_DIN_to_AES) {
			dev_err(dev, "HW key not supported for non-AES flows\n");
			return -EINVAL;
		}

		ctx_p->hw.key1_slot = hw_key_to_cc_hw_key(hki->hw_key1);
		if (ctx_p->hw.key1_slot == END_OF_KEYS) {
			dev_err(dev, "Unsupported hw key1 number (%d)\n",
				hki->hw_key1);
			return -EINVAL;
		}

		if (ctx_p->cipher_mode == DRV_CIPHER_XTS ||
		    ctx_p->cipher_mode == DRV_CIPHER_ESSIV ||
		    ctx_p->cipher_mode == DRV_CIPHER_BITLOCKER) {
			if (hki->hw_key1 == hki->hw_key2) {
				dev_err(dev, "Illegal hw key numbers (%d,%d)\n",
					hki->hw_key1, hki->hw_key2);
				return -EINVAL;
			}
			ctx_p->hw.key2_slot =
				hw_key_to_cc_hw_key(hki->hw_key2);
			if (ctx_p->hw.key2_slot == END_OF_KEYS) {
				dev_err(dev, "Unsupported hw key2 number (%d)\n",
					hki->hw_key2);
				return -EINVAL;
			}
		}

		ctx_p->keylen = keylen;
		dev_dbg(dev, "cc_is_hw_key ret 0");

		return 0;
	}

	// verify weak keys
	if (ctx_p->flow_mode == S_DIN_to_DES) {
		if (!des_ekey(tmp, key) &&
		    (crypto_tfm_get_flags(tfm) & CRYPTO_TFM_REQ_WEAK_KEY)) {
			tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
			dev_dbg(dev, "weak DES key");
			return -EINVAL;
		}
	}
	if (ctx_p->cipher_mode == DRV_CIPHER_XTS &&
	    xts_check_key(tfm, key, keylen)) {
		dev_dbg(dev, "weak XTS key");
		return -EINVAL;
	}
	if (ctx_p->flow_mode == S_DIN_to_DES &&
	    keylen == DES3_EDE_KEY_SIZE &&
	    cc_verify_3des_keys(key, keylen)) {
		dev_dbg(dev, "weak 3DES key");
		return -EINVAL;
	}

	/* STAT_PHASE_1: Copy key to ctx */
	dma_sync_single_for_cpu(dev, ctx_p->user.key_dma_addr,
				max_key_buf_size, DMA_TO_DEVICE);

	memcpy(ctx_p->user.key, key, keylen);
	if (keylen == 24)
		memset(ctx_p->user.key + 24, 0, CC_AES_KEY_SIZE_MAX - 24);

	if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) {
		/* sha256 for key2 - use sw implementation */
		int key_len = keylen >> 1;
		int err;

		SHASH_DESC_ON_STACK(desc, ctx_p->shash_tfm);

		desc->tfm = ctx_p->shash_tfm;

		err = crypto_shash_digest(desc, ctx_p->user.key, key_len,
					  ctx_p->user.key + key_len);
		if (err) {
			dev_err(dev, "Failed to hash ESSIV key.\n");
			return err;
		}
	}
Beispiel #12
0
static int cc_cipher_setkey(struct crypto_skcipher *sktfm, const u8 *key,
			    unsigned int keylen)
{
	struct crypto_tfm *tfm = crypto_skcipher_tfm(sktfm);
	struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
	struct device *dev = drvdata_to_dev(ctx_p->drvdata);
	u32 tmp[DES3_EDE_EXPKEY_WORDS];
	struct cc_crypto_alg *cc_alg =
			container_of(tfm->__crt_alg, struct cc_crypto_alg,
				     skcipher_alg.base);
	unsigned int max_key_buf_size = cc_alg->skcipher_alg.max_keysize;

	dev_dbg(dev, "Setting key in context @%p for %s. keylen=%u\n",
		ctx_p, crypto_tfm_alg_name(tfm), keylen);
	dump_byte_array("key", (u8 *)key, keylen);

	/* STAT_PHASE_0: Init and sanity checks */

	if (validate_keys_sizes(ctx_p, keylen)) {
		dev_err(dev, "Unsupported key size %d.\n", keylen);
		crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
		return -EINVAL;
	}

	ctx_p->hw_key = false;

	/*
	 * Verify DES weak keys
	 * Note that we're dropping the expanded key since the
	 * HW does the expansion on its own.
	 */
	if (ctx_p->flow_mode == S_DIN_to_DES) {
		if (keylen == DES3_EDE_KEY_SIZE &&
		    __des3_ede_setkey(tmp, &tfm->crt_flags, key,
				      DES3_EDE_KEY_SIZE)) {
			dev_dbg(dev, "weak 3DES key");
			return -EINVAL;
		} else if (!des_ekey(tmp, key) &&
			   (crypto_tfm_get_flags(tfm) &
			    CRYPTO_TFM_REQ_FORBID_WEAK_KEYS)) {
			tfm->crt_flags |= CRYPTO_TFM_RES_WEAK_KEY;
			dev_dbg(dev, "weak DES key");
			return -EINVAL;
		}
	}

	if (ctx_p->cipher_mode == DRV_CIPHER_XTS &&
	    xts_check_key(tfm, key, keylen)) {
		dev_dbg(dev, "weak XTS key");
		return -EINVAL;
	}

	/* STAT_PHASE_1: Copy key to ctx */
	dma_sync_single_for_cpu(dev, ctx_p->user.key_dma_addr,
				max_key_buf_size, DMA_TO_DEVICE);

	memcpy(ctx_p->user.key, key, keylen);
	if (keylen == 24)
		memset(ctx_p->user.key + 24, 0, CC_AES_KEY_SIZE_MAX - 24);

	if (ctx_p->cipher_mode == DRV_CIPHER_ESSIV) {
		/* sha256 for key2 - use sw implementation */
		int key_len = keylen >> 1;
		int err;

		SHASH_DESC_ON_STACK(desc, ctx_p->shash_tfm);

		desc->tfm = ctx_p->shash_tfm;

		err = crypto_shash_digest(desc, ctx_p->user.key, key_len,
					  ctx_p->user.key + key_len);
		if (err) {
			dev_err(dev, "Failed to hash ESSIV key.\n");
			return err;
		}
	}
Beispiel #13
0
static int cc_cipher_sethkey(struct crypto_skcipher *sktfm, const u8 *key,
			     unsigned int keylen)
{
	struct crypto_tfm *tfm = crypto_skcipher_tfm(sktfm);
	struct cc_cipher_ctx *ctx_p = crypto_tfm_ctx(tfm);
	struct device *dev = drvdata_to_dev(ctx_p->drvdata);
	struct cc_hkey_info hki;

	dev_dbg(dev, "Setting HW key in context @%p for %s. keylen=%u\n",
		ctx_p, crypto_tfm_alg_name(tfm), keylen);
	dump_byte_array("key", (u8 *)key, keylen);

	/* STAT_PHASE_0: Init and sanity checks */

	/* This check the size of the hardware key token */
	if (keylen != sizeof(hki)) {
		dev_err(dev, "Unsupported HW key size %d.\n", keylen);
		crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
		return -EINVAL;
	}

	if (ctx_p->flow_mode != S_DIN_to_AES) {
		dev_err(dev, "HW key not supported for non-AES flows\n");
		return -EINVAL;
	}

	memcpy(&hki, key, keylen);

	/* The real key len for crypto op is the size of the HW key
	 * referenced by the HW key slot, not the hardware key token
	 */
	keylen = hki.keylen;

	if (validate_keys_sizes(ctx_p, keylen)) {
		dev_err(dev, "Unsupported key size %d.\n", keylen);
		crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
		return -EINVAL;
	}

	ctx_p->hw.key1_slot = cc_slot_to_hw_key(hki.hw_key1);
	if (ctx_p->hw.key1_slot == END_OF_KEYS) {
		dev_err(dev, "Unsupported hw key1 number (%d)\n", hki.hw_key1);
		return -EINVAL;
	}

	if (ctx_p->cipher_mode == DRV_CIPHER_XTS ||
	    ctx_p->cipher_mode == DRV_CIPHER_ESSIV ||
	    ctx_p->cipher_mode == DRV_CIPHER_BITLOCKER) {
		if (hki.hw_key1 == hki.hw_key2) {
			dev_err(dev, "Illegal hw key numbers (%d,%d)\n",
				hki.hw_key1, hki.hw_key2);
			return -EINVAL;
		}
		ctx_p->hw.key2_slot = cc_slot_to_hw_key(hki.hw_key2);
		if (ctx_p->hw.key2_slot == END_OF_KEYS) {
			dev_err(dev, "Unsupported hw key2 number (%d)\n",
				hki.hw_key2);
			return -EINVAL;
		}
	}

	ctx_p->keylen = keylen;
	ctx_p->hw_key = true;
	dev_dbg(dev, "cc_is_hw_key ret 0");

	return 0;
}
Beispiel #14
0
static void RfidTask(void *pvParameters) {
  MFRC522_StatusCode status;
  uint8_t last_uidBytes[MFRC522_UID_MAX_NOF_BYTES];
  int i;
  bool newCardDetected = FALSE;

  (void)pvParameters; /* not used */
  init_uid_bytes(last_uidBytes);
  RFID_uid = NULL;

  vTaskDelay(pdMS_TO_TICKS(1000)); /* give hardware some time to power-up */
  MFRC522_PCD_Init();
  //MFRC522_SetAntennaGain(MFRC522_RxGain_max);
  for(;;) {
    newCardDetected = FALSE;
    RFID_GetLock();
    if (RFID_DoSelfTest) {
      if (!MFRC522_PCD_PerformSelfTest()) {
        CLS1_SendStr("Selftest failed()!\r\n", CLS1_GetStdio()->stdErr);
      }
    }
    if (MFRC522_PICC_IsNewCardPresent()) { /* check if a card responds to PICC_CMD_REQA */
      //CLS1_SendStr("Card detected...\r\n", CLS1_GetStdio()->stdOut);
      if (MFRC522_PICC_ReadCardSerial()) {
        //CLS1_SendStr("Read card serial...\r\n", CLS1_GetStdio()->stdOut);
        RFID_uid = MFRC522_GetUid();

        newCardDetected = TRUE;
        if (RFID_dumpNewCardInformation) {
          MFRC522_PICC_DumpToSerial(RFID_uid);
        } else if (RFID_changeUID) { /* only works with Chinese cards which have the UID writeable! */
          if (!MFRC522_MIFARE_SetUid(RFID_newUID4, sizeof(RFID_newUID4), TRUE)) {
            CLS1_SendStr("Setting new uid failed!\r\n", CLS1_GetStdio()->stdOut);
          } else {
            CLS1_SendStr("Set New ID to card!\r\n", CLS1_GetStdio()->stdOut);
          }
        } else if (RFID_authUID) { /* only for NTAG216! */
          AuthNTag216(RFID_uid);
        } else if (RFID_WriteUltraLight) {
          WriteUltraLight(RFID_uid);
        } else if (RFID_WriteMifare) {
          WriteMifare(RFID_uid);
        } else if (RFID_TryKnownKeys) {
          TryKnownKeys();
        } else if (!same_uid_bytes(last_uidBytes, &RFID_uid->uidByte[0], RFID_uid->size)) {
          CLS1_SendStr("\r\nCard UID:", CLS1_GetStdio()->stdOut);
          dump_byte_array(RFID_uid->uidByte, RFID_uid->size, TRUE);
          CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
          init_uid_bytes(last_uidBytes);

          set_uid_bytes(last_uidBytes, &RFID_uid->uidByte[0], RFID_uid->size);

          CLS1_SendStr("PICC type: ", CLS1_GetStdio()->stdOut);
          PICC_Type piccType = MFRC522_PICC_GetType(RFID_uid->sak);
          CLS1_SendStr(MFRC522_PICC_GetTypeName(piccType), CLS1_GetStdio()->stdOut);
          CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
        } else { /* same card again */
          CLS1_SendStr(".", CLS1_GetStdio()->stdOut);
        }
      }
      MFRC522_PICC_HaltA(); /* Halt PICC */
      MFRC522_PCD_StopCrypto1(); /* Stop encryption on PCD */
    } /* new card present */
    RFID_ReleaseLock();
    if (!newCardDetected) {
      vTaskDelay(pdMS_TO_TICKS(500));
    } else {
      vTaskDelay(pdMS_TO_TICKS(2000));
    }
  }
}
Beispiel #15
0
static void WriteMifare(Uid *uid) {
  MFRC522_MIFARE_Key key;

  PICC_Type piccType = MFRC522_PICC_GetType(uid->sak);
  if (   piccType != PICC_TYPE_MIFARE_MINI
      && piccType != PICC_TYPE_MIFARE_1K
      && piccType != PICC_TYPE_MIFARE_UL
      )
  {
    CLS1_SendStr("Only works with MIFARE classic cards!\r\n", CLS1_GetStdio()->stdErr);
    return;
  }
  // init default access key
  for(int i=0;i<sizeof(key.keyByte);i++) {
    key.keyByte[i] = 0xff;
  }

  // In this sample we use the second sector,
  // that is: sector #1, covering block #4 up to and including block #7
  uint8_t sector         = 1;
  uint8_t blockAddr      = 4;
  uint8_t dataBlock[]    = {
      0x01, 0x02, 0x03, 0x04, //  1,  2,   3,  4,
      0x05, 0x06, 0x07, 0x08, //  5,  6,   7,  8,
      0x09, 0x0a, 0xff, 0x0b, //  9, 10, 255, 11,
      0x0c, 0x0d, 0x0e, 0x0f  // 12, 13, 14, 15
  };
  uint8_t trailerBlock   = 7;
  MFRC522_StatusCode status;
  uint8_t buffer[18];
  uint8_t size = sizeof(buffer);

  // Authenticate using key A
  CLS1_SendStr("Authenticating using key A...\r\n", CLS1_GetStdio()->stdOut);
  status = (MFRC522_StatusCode) MFRC522_PCD_Authenticate(MFRC522_PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, uid);
  if (status != STATUS_OK) {
      CLS1_SendStr("PCD_Authenticate() failed: ", CLS1_GetStdio()->stdOut);
      CLS1_SendStr(MFRC522_GetStatusCodeName(status), CLS1_GetStdio()->stdOut);
      return;
  }

  // Show the whole sector as it currently is
  CLS1_SendStr("Current data in sector:\r\n", CLS1_GetStdio()->stdOut);
  MFRC522_PICC_DumpMifareClassicSectorToSerial(uid, &key, sector);
  CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);

  // Read data from the block
  CLS1_SendStr("Reading data from block ", CLS1_GetStdio()->stdOut);
  CLS1_SendNum8u(blockAddr, CLS1_GetStdio()->stdOut);
  CLS1_SendStr(" ...\r\n", CLS1_GetStdio()->stdOut);
  status = (MFRC522_StatusCode) MFRC522_MIFARE_Read(blockAddr, buffer, &size);
  if (status != STATUS_OK) {
    CLS1_SendStr("MIFARE_Read() failed: ", CLS1_GetStdio()->stdOut);
    CLS1_SendStr(MFRC522_GetStatusCodeName(status), CLS1_GetStdio()->stdOut);
    CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
  }
  CLS1_SendStr("Data in block ", CLS1_GetStdio()->stdOut);
  CLS1_SendNum8u(blockAddr, CLS1_GetStdio()->stdOut);
  CLS1_SendStr(":\r\n", CLS1_GetStdio()->stdOut);
  dump_byte_array(buffer, 16, TRUE);
  CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
  CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);

  // Authenticate using key B
  CLS1_SendStr("Authenticating again using key B...\r\n", CLS1_GetStdio()->stdOut);
  status = (MFRC522_StatusCode) MFRC522_PCD_Authenticate(MFRC522_PICC_CMD_MF_AUTH_KEY_B, trailerBlock, &key, uid);
  if (status != STATUS_OK) {
      CLS1_SendStr("PCD_Authenticate() failed: ", CLS1_GetStdio()->stdOut);
      CLS1_SendStr(MFRC522_GetStatusCodeName(status), CLS1_GetStdio()->stdOut);
      CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
      return;
  }

  // Write data to the block
  CLS1_SendStr("Writing data into block ", CLS1_GetStdio()->stdOut);
  CLS1_SendNum8u(blockAddr, CLS1_GetStdio()->stdOut);
  CLS1_SendStr(" ...\r\n", CLS1_GetStdio()->stdOut);
  dump_byte_array(dataBlock, 16, TRUE);
  CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
  status = (MFRC522_StatusCode) MFRC522_MIFARE_Write(blockAddr, dataBlock, 16);
  if (status != STATUS_OK) {
    CLS1_SendStr("MIFARE_Write() failed: ", CLS1_GetStdio()->stdOut);
    CLS1_SendStr(MFRC522_GetStatusCodeName(status), CLS1_GetStdio()->stdOut);
    CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
  }
  CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);

  // Read data from the block (again, should now be what we have written)
  CLS1_SendStr("Reading data from block ", CLS1_GetStdio()->stdOut);
  CLS1_SendNum8u(blockAddr, CLS1_GetStdio()->stdOut);
  CLS1_SendStr(" ...\r\n", CLS1_GetStdio()->stdOut);
  status = (MFRC522_StatusCode) MFRC522_MIFARE_Read(blockAddr, buffer, &size);
  if (status != STATUS_OK) {
    CLS1_SendStr("MIFARE_Read() failed: ", CLS1_GetStdio()->stdOut);
    CLS1_SendStr(MFRC522_GetStatusCodeName(status), CLS1_GetStdio()->stdOut);
    CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
  }
  CLS1_SendStr("Data in block ", CLS1_GetStdio()->stdOut);
  CLS1_SendNum8u(blockAddr, CLS1_GetStdio()->stdOut);
  CLS1_SendStr(":\r\n", CLS1_GetStdio()->stdOut);
  dump_byte_array(buffer, 16, TRUE);
  CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);

  // Check that data in block is what we have written
  // by counting the number of bytes that are equal
  CLS1_SendStr("Checking result...", CLS1_GetStdio()->stdOut);
  uint8_t count = 0;
  for (uint8_t i = 0; i < 16; i++) {
      // Compare buffer (= what we've read) with dataBlock (= what we've written)
      if (buffer[i] == dataBlock[i]) {
          count++;
      }
  }
  CLS1_SendStr("Number of bytes that match = ", CLS1_GetStdio()->stdOut);
  CLS1_SendNum8u(count, CLS1_GetStdio()->stdOut);
  CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
  if (count == 16) {
    CLS1_SendStr("Success :-)\r\n", CLS1_GetStdio()->stdOut);
  } else {
    CLS1_SendStr("Failure, no match :-(\r\n", CLS1_GetStdio()->stdOut);
    CLS1_SendStr("  perhaps the write didn't work properly...\r\n", CLS1_GetStdio()->stdOut);
  }
  CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);

  // Dump the sector data
  CLS1_SendStr("Current data in sector:\r\n", CLS1_GetStdio()->stdOut);
  MFRC522_PICC_DumpMifareClassicSectorToSerial(uid, &key, sector);
  CLS1_SendStr("\r\n", CLS1_GetStdio()->stdOut);
}