static int
print_write_protect_status(struct mmc_card *card, char *buffer)
{
  struct another_mmc_csd csd;
  u32 write_protect_group_size;
  u32 group_count;
  u32 status;
  u32 address;
  int error;
  int ret = 0;

  mmc_claim_host(card->host);

  get_csd(card, &csd);

  write_protect_group_size = (csd.erase_grp_size + 1) * (csd.erase_grp_mult + 1) * (csd.wp_grp_size + 1);
  group_count = card->ext_csd.sectors / write_protect_group_size;

  error = get_card_status(card, &status);
  if (error) {
    mmc_release_host(card->host);
    return 0;
  }

  for (address = 0; address < group_count; address += WRITE_PROTECT_INFO_BITS) {
    u64 write_protect_status;
    error = mmc_send_cxd_data(card, card->host,
                              CMD31_SEND_WRITE_PROT_TYPE,
                              address * write_protect_group_size,
                              MMC_CMD_ADTC | MMC_RSP_R1,
                              &write_protect_status, sizeof(write_protect_status));
    if (error) {
      printk(KERN_ERR "Failed to get write protect status %x\n", error);
      mmc_release_host(card->host);
      return ret;
    }
    ret += sprintf(buffer + ret, "0x%08x (0x%016llx)\n",
                   address * write_protect_group_size, write_protect_status);
  }

  mmc_release_host(card->host);
  return ret;
}
static bool
clear_write_protect(struct mmc_card *card, u32 start, u32 size)
{
  struct another_mmc_csd csd;
  struct mmc_command cmd;
  u32 write_protect_group_size;
  int error;
  unsigned int i, loop_count;

  mmc_claim_host(card->host);

  get_csd(card, &csd);

  write_protect_group_size = (csd.erase_grp_size + 1) * (csd.erase_grp_mult + 1) * (csd.wp_grp_size + 1);

  memset(&cmd, 0, sizeof(struct mmc_command));

  cmd.opcode = MMC_CLR_WRITE_PROT;
  cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;

  loop_count = (size / write_protect_group_size) + 1;
  for (i = 0; i < loop_count; i++) {
    u32 status;
    cmd.arg = start + i * write_protect_group_size;
    error = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
    if (error) {
      break;
    }
    error = get_card_status(card, &status);
    if (error) {
      break;
    }
  }

  if (error) {
    printk(KERN_ERR "Failed to clear write protect error(%x)\n", error);
  }

  mmc_release_host(card->host);

  return true;
}
Exemple #3
0
int handleCommands(FILE *fd)
{
    BYTE buf[BUFLEN + 1];
    int rv = 0, i;
    char *token;
    OptionStr optionStr;

    while (fgets (buf, BUFLEN, fd) != NULL) {	
	token = strtokCheckComment(buf);
	while (token != NULL) {
	    if (token[0] == '#' || strncmp (token, "//", 2) == 0)
		break;
	    if (strcmp(token, "establish_context") == 0) {
		// Establish context
		rv = establish_context(&cardContext);
		if (rv != OPSP_ERROR_SUCCESS) {
		    printf ("establish_context failed with error %d\n", rv);
		    exit (1);
		}
		break;
	    } else if (strcmp(token, "release_context") == 0) {
		// Release context
		rv = release_context(cardContext);
		if (rv != OPSP_ERROR_SUCCESS) {
		    printf ("release_context failed with error %d\n", rv);
		    exit (1);
		}

		break;
	    } else if (strcmp(token, "card_connect") == 0) {
		TCHAR buf[BUFLEN + 1];
		DWORD readerStrLen = BUFLEN;
		// open reader
		handleOptions(&optionStr);
#ifdef DEBUG
		printf ("optionStr.reader %d\n", optionStr.reader);
#endif
		if (optionStr.reader == NULL) {	
		    // get the first reader
		    rv = list_readers (cardContext, buf, &readerStrLen);

		    optionStr.reader = buf;
#ifdef DEBUG
		    _tprintf ( _T("reader name %s\n"), optionStr.reader);
#endif
		}
		
		rv = card_connect (cardContext, optionStr.reader,
				   &cardHandle, optionStr.protocol);

		if (rv != 0) {
		    _tprintf (_T("card_connect() returns %d (%s)\n"), rv,
			      stringify_error(rv));
		}

		rv = get_card_status (cardHandle, &cardInfo);
		if (rv != 0) {
		    _tprintf (_T("get_card_status() returns %d (%s)\n"), rv,
			      stringify_error(rv));
		    exit (1);
		}
		
		break;
	    } if (strcmp(token, "open_sc") == 0) {
		// open secure channel
		handleOptions(&optionStr);
		/*for (i=0; i<TDES_KEY_LEN; i++) {
		  printf ("%02x ", optionStr.key[i]);
		  }*/
		rv = mutual_authentication(cardHandle,
					   optionStr.enc_key,
					   optionStr.mac_key,
					   optionStr.keySetVersion,
					   optionStr.keyIndex,
					   cardInfo,
					   optionStr.securityLevel,
					   &securityInfo);
		if (rv != 0) {
		    _tprintf (_T("mutual_authentication() returns %d (%s)\n"),
			      rv, stringify_error(rv));
		    exit (1);
		}
					       
		break;
	    } else if (strcmp(token, "select") == 0) {
		// select instance
		handleOptions(&optionStr);
		rv = select_application (cardHandle, cardInfo,
					 optionStr.AID, optionStr.AIDLen);
		if (rv != 0) {
		    _tprintf (_T("select_application() returns %d (%s)\n"),
			      rv, stringify_error(rv));
		    exit (1);
		}
		break;
	    } else if (strcmp(token, "getdata") == 0) {
		// Get Data
		handleOptions(&optionStr);
		// TODO: get data
		break;
	    } else if (strcmp(token, "load") == 0) {
		// Load Applet
		DWORD receiptDataLen = 0;
		handleOptions(&optionStr);

		rv = load_applet(cardHandle, &securityInfo, cardInfo,
				 NULL, 0, optionStr.file,
				 NULL, &receiptDataLen);
		if (rv != 0) {
		    _tprintf (_T("load_applet() returns %d (%s)\n"),
			      rv, stringify_error(rv));
		    exit (1);
		}

		break;
	    }  else if (strcmp(token, "delete") == 0) {
		// Delete Applet
		OPSP_AID AIDs[1];
		OPSP_RECEIPT_DATA receipt[10];
		DWORD receiptLen = 10;
		    
		handleOptions(&optionStr);
		memcpy (AIDs[0].AID, optionStr.AID, optionStr.AIDLen);
		AIDs[0].AIDLength = optionStr.AIDLen;

		rv = delete_applet(cardHandle, &securityInfo,
				   cardInfo,
				   AIDs, 1,
                                   (OPSP_RECEIPT_DATA **)&receipt, &receiptLen);

		if (rv != 0) {
		    _tprintf (_T("delete_applet() returns %d (%s)\n"),
			      rv, stringify_error(rv));
		}
		break;
	    }
    
	    else if (strcmp(token, "install_for_load") == 0) {
		// Install for Load
		handleOptions(&optionStr);

		rv = install_for_load(cardHandle, &securityInfo,
				      cardInfo,
				      optionStr.AID, optionStr.AIDLen,
				      optionStr.sdAID, optionStr.sdAIDLen,
				      NULL, NULL,
				      optionStr.nvCodeLimit,
				      optionStr.nvDataLimit,
				      optionStr.vDataLimit);
				      
		if (rv != 0) {
		    _tprintf (_T("install_for_load() returns %d (%s)\n"),
			      rv, stringify_error(rv));
		    exit (1);
		}
		break;
	    } else if (strcmp(token, "install_for_install") == 0) {
		OPSP_RECEIPT_DATA receipt;
		DWORD receiptDataAvailable = 0;
		char installParam[1];
		installParam[0] = 0;

		// Install for Install
		handleOptions(&optionStr);
		
		rv = install_for_install_and_make_selectable(
					 cardHandle, &securityInfo,
					 cardInfo,
					 optionStr.pkgAID, optionStr.pkgAIDLen,
					 optionStr.AID, optionStr.AIDLen,
					 optionStr.instAID, optionStr.instAIDLen,
					 OPSP_APPLICATION_PRIVILEGE_PIN_CHANGE_PRIVILEGE, // 
					 optionStr.vDataLimit,
					 optionStr.nvDataLimit,
					 optionStr.instParam,
					 optionStr.instParamLen, 
					 NULL, // No install token
					 &receipt,
					 &receiptDataAvailable);

		if (rv != 0) {
		    _tprintf (_T("install_for_install_and_make_selectable() returns %d (%s)\n"),
			      rv, stringify_error(rv));
		    exit (1);
		}
		break;
	    } else if (strcmp(token, "card_disconnect") == 0) {
		// disconnect card
		card_disconnect(cardHandle);

		break;
	    } else if (strcmp(token, "put_sc_key") == 0) {
		handleOptions(&optionStr);

		rv = put_secure_channel_keys(cardHandle, &securityInfo,
					     cardInfo,
					     optionStr.keySetVersion,
					     optionStr.newKeySetVersion,
					     optionStr.enc_key,
					     optionStr.mac_key,
					     optionStr.kek_key,
					     optionStr.current_kek);
		
		if (rv != 0) {
		    _tprintf (_T("put_secure_channel_keys() returns %d (%s)\n"),
			      rv, stringify_error(rv));
		    exit (1);
		}
		break;
	    } else if (strcmp(token, "get_status") == 0) {
#define NUM_APPLICATIONS 64
		OPSP_APPLICATION_DATA data[NUM_APPLICATIONS];
		DWORD numData = NUM_APPLICATIONS;

		handleOptions(&optionStr);
		
		rv = get_status(cardHandle, &securityInfo, cardInfo,
				optionStr.element,
				data,
				&numData);
		if (rv != 0) {
		    _tprintf (_T("get_status() returns %d (%s)\n"),
			      rv, stringify_error(rv));
		    exit (1);
		}
#ifdef DEBUG
		printf ("get_status() returned %d items\n", numData);
#endif
		printf ("\nList of applets (AID state privileges)\n");
		for (i=0; i<numData; i++) {
		    int j;
		    
		    for (j=0; j<data[i].AIDLength; j++) {
			printf ("%02x", data[i].AID[j]);
		    }

		    printf ("\t%x", data[i].lifeCycleState);
		    printf ("\t%x\n", data[i].privileges);
		}
		
		break;
	    } else if (strcmp(token, "send_apdu") == 0) {
		unsigned char recvAPDU[257];
		int recvAPDULen = 257, i;
		// Install for Load
		handleOptions(&optionStr);

		printf ("Send APDU: ");
		for (i=0; i<optionStr.APDULen; i++)
		    printf ("%02x ", optionStr.APDU[i]);
		printf ("\n");
		
		rv = send_APDU(cardHandle, 
			       optionStr.APDU, optionStr.APDULen, 
			       recvAPDU, &recvAPDULen,
			       cardInfo,
			       (optionStr.secureChannel == 0 ? NULL : &securityInfo));
		if (rv != 0) {
		    _tprintf (_T("send_APDU() returns %d (%s)\n"),
			      rv, stringify_error(rv));
		    exit (1);
		}

		printf ("Recv APDU: ");
		for (i=0; i<recvAPDULen; i++)
		    printf ("%02x ", recvAPDU[i]);
		printf ("\n");
		
		break;
	    } else {
		printf ("Unknown command %s\n", token);
		exit (1);
	    }

	    token = strtokCheckComment(NULL);
	}
    }

    return rv;
}