Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SetKey request #126

Closed
Peterthegreat opened this issue Jul 25, 2017 · 7 comments
Closed

SetKey request #126

Peterthegreat opened this issue Jul 25, 2017 · 7 comments
Assignees

Comments

@Peterthegreat
Copy link

Peterthegreat commented Jul 25, 2017

Hi,

I am doing a project which requires to change the keys on the go. Taking the SetUid command as an example, I made the SetKey function which should be something like this:

void MifareClassicSetKey( uint8_t Key[6], uint8_t Sector, bool Auth)
{
uint8_t SectorAddress = Sector & MEM_SECTOR_ADDR_MASK;
uint16_t KeyAddress;

if (Auth==0)
{
	KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + MEM_KEY_A_OFFSET;
}
else
{
	KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + MEM_KEY_B_OFFSET;
}

MemoryWriteBlock(Key, KeyAddress, 6);

}`

The parsing is made in Commands.h with strtok:

CommandStatusIdType CommandSetKey(char* OutMessage, const char* InParam)
{
uint8_t KeyBuffer[COMMAND_KEY_BUFSIZE];

ApplicationReset();

char *input = InParam;
char *token = strtok(input, "@");
uint8_t *token1 = atoi(strtok(NULL, "@"));
uint8_t token2 = atoi(strtok(NULL, "@"));
....

The problem is that this functions only change the key A form sector 0, no matter which parameters I enter. Any help would be appreciated.

@geo-rg geo-rg self-assigned this Jul 26, 2017
@geo-rg
Copy link
Collaborator

geo-rg commented Jul 26, 2017

In which format do you want to pass the key? I think something like setkey <sector> <A/B> <key>, e.g., setkey 5 A 00AA22FF4455 would be a good idea.
I think strtok is not a good choice here. Since the format is known to us, I would suggest the following procedure:

  1. Check where the first non-whitespace character occurs and save the pointer to this position.
  2. Run strtol on that string (the pointer from 1), check whether the value is a valid sector number and also get the pointer to the character after the integer from this function.
  3. Check, beginning from the pointer which you have from strtol, where the first non-whitespace character occurs.
  4. Check whether the found character is A or B (or a or b).
  5. Again check where the next non-whitespace character occurs.
  6. Get the key either with strtol or with sscanf.

Another - much simpler - idea would be to hard-code the offsets and thus suppose that the user separates the parameters only with one whitespace.

I also suppose that you have meant Commands.c instead of .h? Another very important thing is that you have declared your function in CommandLine.c as ExecParamFunc.

@Peterthegreat
Copy link
Author

Peterthegreat commented Jul 26, 2017

The format for passing the key is not important for me.

Since it is a quick and dirty code, I can go for hard-coding the offsets, and I don't see any problem using strtok.

I also suppose that you have meant Commands.c instead of .h?

Yes

Another very important thing is that you have declared your function in CommandLine.c as ExecParamFunc.

Actually, it is declared as ".SetFunc = CommandSetKey,". Right now, the command looks like: KEY=00AA11223344@15@1.

My question is regarding the Sector value that must be set.
Which value should the variable Sector have? (I guess 160 for sector 15)

@geo-rg
Copy link
Collaborator

geo-rg commented Jul 27, 2017

Have a look at Application/MifareClassic.c. If you want to authenticate for sector 15 (i.e. you have sent 0x600F to the card), then line 622 masks the 15 to 12 and the key is read here from position 12*16+48 = 240 (for key B it would be 250).

@skuep
Copy link
Collaborator

skuep commented Jul 27, 2017

If you want to use sscanf, this is from another project of mine that stems from the same original CommandLine sources. The command syntax here is AUXPLLWRITE <RegisterHex> <ValueHex>

CommandStatusIdType CommandExecAuxPLLWrite(char* OutMessage, const char* InParam)
{
    uint32_t Register;
    uint32_t Value;

    /* Try to parse params using scanf */
    if (sscanf(InParam, "%" SCNx32 " %" SCNx32, &Register, &Value) == 2) {
        AuxPLLWriteRegister(Register, Value);

        return COMMAND_INFO_OK_ID;
    } else {
        return COMMAND_ERR_INVALID_PARAM_ID;
    }
}

@Peterthegreat
Copy link
Author

@skuep Thanks for the suggestion. I think it's actually a better approach.

@geo-rg I already looked at the suggested lines in Application/MifareClassic.c. I think my problem is still on the parsing and setting the function parameters. I am now trying to debug the code, but I can't get any output from printf inside my functions.

Ultimately, I need to call the function from Software/chamlog.py. So again, I looked for something similar, which is the setUID command. The problem is that even this function (called in chamlog.py with chameleon.cmdUID("99999999") ) returns an error (below). The UID is set, but the python script halts. Can you reproduce the issue?

\Software\Chameleon\Device.py", line 128, in writeCmd status = self.serial.readline().decode('ascii').rstrip() UnicodeDecodeError: 'ascii' codec can't decode byte 0xc7 in position 2: ordinal not in range(128)

Thanks

@Peterthegreat
Copy link
Author

SetKey now works, thanks for the help.

Regarding the python command, maybe I am calling it wrong? Right now i am bypassing the error with try/except:pass, but it would be nice to see a response.

@Peterthegreat
Copy link
Author

Closing this, as SetKey now works and setUID in not related to this topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants