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;
}