Yubico / yubikey-personalization

YubiKey Personalization cross-platform library and tool
https://developers.yubico.com/yubikey-personalization/
BSD 2-Clause "Simplified" License
299 stars 82 forks source link

yk_challenge_response() returns 22 bytes response instead of expected 20 #124

Closed smrt28 closed 5 years ago

smrt28 commented 5 years ago

Hi,

I have YubiKey 4. Slot 1 is configured with HMAC.

ykpersonalize -1 -ochal-resp -ochal-hmac -ohmac-lt64

It seems yk_challenge_response() returns 22 bytes response instead of expected 20 bytes. By definition, the yk_challenge_response() function should fill ony 20 bytes in response but it seems 22 bytes are returned instead. They are not zeros and they changes with the input so they seems to be part of the hash.

Maybe, those 2 bytes are suppose to be undefined by yk_challenge_response() definition and so the behavior is correct and I should ignore them, but it is strange.

The example code calculates HMAC from the string and prints response. First 22 bytes are not zeros (well, they are zeros in 1/256 cases ;-)). Isn't it strange?

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <string.h>

#include <yubikey.h>
#include <ykdef.h>
#include <ykcore.h>
#include <ykstatus.h>

int main(int argc, char **argv) {
    YK_KEY *yk = 0;

    if (!yk_init()) {
        fprintf(stderr, "yk_init failed\n");
        exit(1);
    }
    if (!(yk = yk_open_key(0))) {
        fprintf(stderr, "yk_open_key failed\n");
        exit(1);
    }

    int i;
    unsigned char *challenge = "xxsx";
    unsigned int len = strlen(challenge);
    unsigned char response[SHA1_MAX_BLOCK_SIZE];
    memset(response, 0, sizeof(response));
    int yk_cmd = SLOT_CHAL_HMAC1;
    if(! yk_challenge_response(yk, yk_cmd, true, len,
                challenge, sizeof(response), response)) {
        fprintf(stderr, "yk_challenge_response failed\n");
        exit(1);
    }
    for (i = 0; i < sizeof(response); ++i) {
        printf("%d\n", (int)response[i]);
    }

    return 0;
}
klali commented 5 years ago

This is expected, the two extra bytes are the CRC of the data.

The buffer needs extra space for the CRC, then padded out to a multiple of 8 since a feature report being read is 8 bytes, and then extra space for one report of 8 bytes since an extra report is sent at the end to indicate a complete command.