Listing 3: Symmetric key license generation and verification

int genl_symm_generate(char *license,

size_t license_size,

u64 target_id,

u16 exp_date,

u16 features,

const void *symm_key)

{

unsigned char licdata[12];

unsigned char mac[SHA1_OUTPUT_LEN];

unsigned char userlic[10];

assert(license_size > sizeof(licdata)*2);

/* copy data into place */

memcpy(licdata,

(char *)&target_id, sizeof(target_id));

memcpy(licdata + sizeof(target_id),

(char *)&exp_date, sizeof(exp_date));

memcpy(licdata + sizeof(target_id) + sizeof(exp_date),

(char *)&features, sizeof(features));

hmac_sha1(mac, sizeof(mac),

licdata, sizeof(licdata),

symm_key, sizeof(symm_key));

/* create the license string */

memcpy(userlic,

(char *)&exp_date, sizeof(exp_date));

memcpy(userlic + sizeof(exp_date),

(char *)&features, sizeof(features));

memcpy(userlic + sizeof(exp_date) + sizeof(features),

mac, sizeof(userlic) -

(sizeof(exp_date) + sizeof(features)));

/* format it nicely */

utils_bin2str(license, license_size,

userlic, sizeof(userlic));

return 0;

}

int verl_symm_verify(const char *license,

u64 target_id,

const void *symm_key,

u16 *exp_date,

u16 *features,

u8 *isValid)

{

unsigned char lic_bin[10];

size_t licdata_len;

unsigned char licdata[12];

unsigned char mac[SHA1_OUTPUT_LEN];

unsigned char userlic[10];

/* parse the license */

utils_str2bin(lic_bin, sizeof(lic_bin),

&licdata_len, license);

memcpy(exp_date, lic_bin, sizeof(*exp_date));

memcpy(features, lic_bin+sizeof(*exp_date),

sizeof(*features));

/* reconstruct the HMACed data */

memcpy(licdata,

(char *)&target_id, sizeof(target_id));

memcpy(licdata + sizeof(target_id),

(char *)exp_date, sizeof(*exp_date));

memcpy(licdata + sizeof(target_id) + sizeof(*exp_date),

(char *)features, sizeof(*features));

hmac_sha1(mac, sizeof(mac),

licdata, sizeof(licdata),

symm_key, sizeof(symm_key));

{

/* compare the leftmost bits */

int offset = sizeof(*exp_date)+sizeof(*features);

*isValid = 0;

if (memcmp(lic_bin+offset, mac,

sizeof(lic_bin) - offset) == 0)

{

*isValid = 1;

}

}

return 0;

}