/** 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); }
/* * 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; }
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")); }
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; }
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; }
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; }
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; } }
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; } }
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; }
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)); } } }
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); }