Exemple #1
0
/**
 * Calculates the hash of the given message and hashtype
 */
int hash(int hashtype, const unsigned char *src, unsigned int srclen,
         unsigned char *dest, unsigned int *destlen)
{
    HCRYPTHASH hash;
    ALG_ID alg;
    int hashlen, rval;
    DWORD _destlen;

    hashlen = get_hash_len(hashtype);
    alg = get_hash(hashtype);

    if (!CryptCreateHash(base_prov, alg, 0, 0, &hash)) {
        mserror("CryptCreateHash failed");
        return 0;
    }
    if (!CryptHashData(hash, src, srclen, 0)) {
        mserror("CryptHashData failed");
        rval = 0;
        goto end;
    }
    _destlen = hashlen;
    if (!CryptGetHashParam(hash, HP_HASHVAL, dest, &_destlen, 0)) {
        mserror("CryptGetHashParam failed");
        rval = 0;
        goto end;
    }
    *destlen = _destlen;
    rval = 1;

end:
    if (!CryptDestroyHash(hash)) {
        mserror("CryptDestroyHash failed");
    }
    return rval;
}
Exemple #2
0
/**
 * Initialize crypto library, generate keys
 */
void key_init()
{
    unsigned char *prf_buf;
    time_t t;
    uint32_t t2;
    int explen, len;

    if (keytype == KEY_NONE) {
        return;
    }

    set_sys_keys(sys_keys);
    get_key_info(keytype, &keylen, &ivlen);
    hmaclen = get_hash_len(hashtype);

    memset(groupkey, 0, sizeof(groupkey));
    memset(groupsalt, 0, sizeof(groupsalt));
    memset(grouphmackey, 0, sizeof(grouphmackey));

    if (!get_random_bytes(groupmaster, sizeof(groupmaster))) {
        log(0, 0, "Failed to generate group master");
        exit(1);
    }
    groupmaster[0] = UFTP_VER_NUM;
    if (!get_random_bytes(rand1, sizeof(rand1))) {
        log(0, 0, "Failed to generate rand1");
        exit(1);
    }
    // Sets the first 4 bytes of rand1 to the current time
    t = time(NULL);
    t2 = (uint32_t)(t & 0xFFFFFFFF);
    *(uint32_t *)rand1 = t2;

    explen = hmaclen + keylen + ivlen;
    prf_buf = calloc(explen + hmaclen, 1);
    if (prf_buf == NULL) {
        syserror(0, 0, "calloc failed!");
        exit(1);
    }
    PRF(hashtype, explen, groupmaster, sizeof(groupmaster), "key expansion",
            rand1, sizeof(rand1), prf_buf, &len);
    memcpy(grouphmackey, prf_buf, hmaclen);
    memcpy(groupkey, prf_buf + hmaclen, keylen);
    memcpy(groupsalt, prf_buf + hmaclen + keylen, ivlen);
    free(prf_buf);

    if ((!strcmp(keyfile, "")) || (newkeylen != 0)) {
        privkey = gen_RSA_key(newkeylen, RSA_EXP, keyfile);
    } else {
        privkey = read_RSA_key(keyfile);
    }
    if (!privkey) {
        log(0, 0, "Failed to read/generate private key");
        exit(1);
    }

    rsalen = RSA_keylen(privkey);
}
Exemple #3
0
/**
 * Hashes a block of data and verifies it against an RSA signature.
 */
int verify_RSA_sig(RSA_key_t rsa, int hashtype,
                   const unsigned char *mes, unsigned int meslen,
                   unsigned char *sig, unsigned int siglen)
{
    HCRYPTHASH hash;
    ALG_ID alg;
    unsigned hashlen, i;
    int rval;
    unsigned char *insig;

    hashlen = get_hash_len(hashtype);
    alg = get_hash(hashtype);

    if (!CryptCreateHash(base_prov, alg, 0, 0, &hash)) {
        mserror("CryptCreateHash failed");
        return 0;
    }
    if (!CryptHashData(hash, mes, meslen, 0)) {
        mserror("CryptHashData failed");
        rval = 0;
        goto end;
    }
    insig = calloc(siglen, 1);
    if (insig == NULL) {
        syserror(0, 0, "calloc failed!");
        exit(1);
    }
    // CryptoAPI expects signatures in little endian, so reverse the bytes
    for (i = 0; i < siglen; i++) {
        insig[i] = sig[siglen - i - 1];
    }
    if (!CryptVerifySignature(hash, insig, siglen, rsa, NULL, 0)) {
        mserror("CryptVerifySignature failed");
        free(insig);
        rval = 0;
        goto end;
    }
    free(insig);

    rval = 1;

end:
    if (!CryptDestroyHash(hash)) {
        mserror("CryptDestroyHash failed");
    }
    return rval;
}
Exemple #4
0
/**
 * Hashes a block of data and signs it with an RSA private key.
 * Output buffer must be at least the key size.
 */
int create_RSA_sig(RSA_key_t rsa, int hashtype,
                   const unsigned char *mes, unsigned int meslen,
                   unsigned char *sig, unsigned int *siglen)
{
    HCRYPTHASH hash;
    DWORD _siglen;
    int idx, found;
    ALG_ID alg;
    int hashlen, rval;
    unsigned int i;
    unsigned char *outsig;

    for (idx = 0, found = 0; (idx < MAXLIST) && (!found); idx++) {
        if (private_key_list[idx].key == rsa) {
            found = 1;
        }
    }
    if (!found) {
        log(0, 0, "Couldn't find provider for RSA key");
        return 0;
    }
    idx--;

    hashlen = get_hash_len(hashtype);
    alg = get_hash(hashtype);

    if (!CryptCreateHash(private_key_list[idx].provider, alg, 0, 0, &hash)) {
        mserror("CryptCreateHash failed");
        return 0;
    }
    if (!CryptHashData(hash, mes, meslen, 0)) {
        mserror("CryptHashData failed");
        rval = 0;
        goto end;
    }

    _siglen = RSA_keylen(rsa);
    outsig = calloc(_siglen, 1);
    if (outsig == NULL) {
        syserror(0, 0, "calloc failed!");
        exit(1);
    }
    if (!CryptSignHash(hash, AT_KEYEXCHANGE, NULL, 0, outsig, &_siglen)) {
        mserror("CryptSignHash failed");
        free(outsig);
        rval = 0;
        goto end;
    }
    *siglen = _siglen;
    // CryptoAPI returns signatures in little endian, so reverse the bytes
    for (i = 0; i < _siglen; i++) {
        sig[i] = outsig[_siglen - i - 1];
    }
    free(outsig);

    rval = 1;

end:
    if (!CryptDestroyHash(hash)) {
        mserror("CryptDestroyHash failed");
    }
    return rval;
}
Exemple #5
0
/**
 * Calculates the HMAC of the given message, hashtype, and hashkey.
 * dest must be at least the hash length.
 */
int create_hmac(int hashtype, const unsigned char *key, unsigned int keylen,
                const unsigned char *src, unsigned int srclen,
                unsigned char *dest, unsigned int *destlen)
{
    // TODO: right now we reimport the hmac key each time.  Test to see if this
    // is quick enough or if we need to cache an imported hmac key.
    HCRYPTKEY hmackey;
    HCRYPTHASH hash;
    char keyblob[BLOBLEN];
    BLOBHEADER *bheader;
    DWORD *keysize;
    BYTE *keydata;
    HMAC_INFO info;
    ALG_ID alg;
    int bloblen, hashlen, rval;
    DWORD _destlen;

    hashlen = get_hash_len(hashtype);
    alg = get_hash(hashtype);

    bheader = (BLOBHEADER *)keyblob;
    keysize = (DWORD *)(keyblob + sizeof(BLOBHEADER));
    keydata = (BYTE *)((char *)keysize + sizeof(DWORD));

    memset(keyblob, 0, sizeof(keyblob));
    bheader->bType = PLAINTEXTKEYBLOB;
    bheader->bVersion = CUR_BLOB_VERSION;
    bheader->aiKeyAlg = CALG_RC2;
    *keysize = keylen;
    memcpy(keydata, key, keylen);
    bloblen = sizeof(BLOBHEADER) + sizeof(DWORD) + hashlen;

    if (!CryptImportKey(base_prov, keyblob, bloblen, 0,
                        CRYPT_IPSEC_HMAC_KEY, &hmackey)) {
        mserror("CryptImportKey failed");
        return 0;
    }

    if (!CryptCreateHash(base_prov, CALG_HMAC, hmackey, 0, &hash)) {
        mserror("CryptCreateHash failed");
        rval = 0;
        goto end1;
    }
    memset(&info, 0, sizeof(info));
    info.HashAlgid = alg;
    if (!CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&info, 0)) {
        mserror("CryptSetHashParam failed");
        rval = 0;
        goto end2;
    }
    if (!CryptHashData(hash, src, srclen, 0)) {
        mserror("CryptHashData failed");
        rval = 0;
        goto end2;
    }
    _destlen = hashlen;
    if (!CryptGetHashParam(hash, HP_HASHVAL, dest, &_destlen, 0)) {
        mserror("CryptGetHashParam failed");
        rval = 0;
        goto end2;
    }
    *destlen = _destlen;
    rval = 1;

end2:
    if (!CryptDestroyHash(hash)) {
        mserror("CryptDestroyHash failed");
    }
end1:
    if (!CryptDestroyKey(hmackey)) {
        mserror("CryptDestroyKey failed");
    }
    return rval;
}
Exemple #6
0
/**
 * Calculate the master key and do key expansion to determine the symmetric
 * cypher key and IV salt, and hash key for the server
 */
int calculate_server_keys(struct group_list_t *group,
                          const struct enc_info_he *encinfo)
{
    unsigned char *seed, *prf_buf;
    int explen, len, seedlen;
    time_t t;
    uint32_t t2;

    memcpy(group->rand1, encinfo->rand1, sizeof(encinfo->rand1));
    if (!get_random_bytes(group->rand2, sizeof(group->rand2))) {
        glog0(group, "Failed to get random bytes for rand2");
        send_abort(group, "Failed to get random bytes for rand2");
        return 0;
    }
    // Sets the first 4 bytes of rand2 to the current time
    t = time(NULL);
    t2 = (uint32_t)(t & 0xFFFFFFFF);
    *(uint32_t *)(group->rand2) = t2;
    if (group->keyextype == KEYEX_RSA) {
        if (!get_random_bytes(group->premaster, MASTER_LEN)) {
            glog0(group, "Failed to get random bytes for premaster");
            send_abort(group, "Failed to get random bytes for premaster");
            return 0;
        }
        group->premaster_len = MASTER_LEN;
    } else {
        EC_key_t pubecdh;

        if (has_proxy) {
            pubecdh = proxy_dhkey.ec;
        } else {
            pubecdh = group->server_dhkey.ec;
        }
        if (!get_ECDH_key(pubecdh, group->client_dhkey.ec,
                          group->premaster, &group->premaster_len)) {
            glog0(group, "Failed to calculate ECDH key");
            send_abort(group, "Failed to calculate ECDH key");
            return 0;
        }
    }

    get_key_info(group->keytype, &group->keylen, &group->ivlen);
    group->hmaclen = get_hash_len(group->hashtype);

    explen = group->keylen + SALT_LEN + group->hmaclen;
    seedlen = RAND_LEN * 2;
    seed = safe_calloc(seedlen, 1);
    prf_buf = safe_calloc(MASTER_LEN + explen + group->hmaclen, 1);

    memcpy(seed, group->rand1, sizeof(group->rand1));
    memcpy(seed + sizeof(group->rand1), group->rand2, sizeof(group->rand2));
    PRF(group->hashtype, MASTER_LEN, group->premaster, group->premaster_len,
            "master secret", seed, seedlen, prf_buf, &len);
    memcpy(group->master,prf_buf, sizeof(group->master));

    PRF(group->hashtype, explen, group->master, sizeof(group->master),
            "key expansion", seed, seedlen, prf_buf, &len);
    memcpy(group->hmackey, prf_buf, group->hmaclen);
    memcpy(group->key, prf_buf + group->hmaclen, group->keylen);
    memcpy(group->salt, prf_buf + group->hmaclen + group->keylen, SALT_LEN);

    free(seed);
    free(prf_buf);
    return 1;
}
Exemple #7
0
/**
 * Initialize crypto library, generate keys
 */
void key_init(void)
{
    unsigned char *prf_buf;
    time_t t;
    uint32_t t2;
    int explen, len;

    if (keytype == KEY_NONE) {
        return;
    }

    set_sys_keys(sys_keys);
    get_key_info(keytype, &keylen, &ivlen);
    hmaclen = get_hash_len(hashtype);

    memset(groupkey, 0, sizeof(groupkey));
    memset(groupsalt, 0, sizeof(groupsalt));
    memset(grouphmackey, 0, sizeof(grouphmackey));

    if (!get_random_bytes(groupmaster, sizeof(groupmaster))) {
        log0(0, 0, 0, "Failed to generate group master");
        exit(ERR_CRYPTO);
    }
    groupmaster[0] = UFTP_VER_NUM;
    if (!get_random_bytes(rand1, sizeof(rand1))) {
        log0(0, 0, 0, "Failed to generate rand1");
        exit(ERR_CRYPTO);
    }
    // Sets the first 4 bytes of rand1 to the current time
    t = time(NULL);
    t2 = (uint32_t)(t & 0xFFFFFFFF);
    *(uint32_t *)rand1 = t2;

    explen = hmaclen + keylen + SALT_LEN;
    prf_buf = safe_calloc(explen + hmaclen, 1);
    PRF(hashtype, explen, groupmaster, sizeof(groupmaster), "key expansion",
            rand1, sizeof(rand1), prf_buf, &len);
    memcpy(grouphmackey, prf_buf, hmaclen);
    memcpy(groupkey, prf_buf + hmaclen, keylen);
    memcpy(groupsalt, prf_buf + hmaclen + keylen, SALT_LEN);
    ivctr = 0;
    free(prf_buf);

    if ((keyextype == KEYEX_RSA) || (keyextype == KEYEX_ECDH_RSA)) {
        if ((!strcmp(keyfile, "")) || (newkeylen != 0)) {
            privkey.rsa = gen_RSA_key(newkeylen, RSA_EXP, keyfile);
        } else {
            privkey.rsa = read_RSA_key(keyfile);
        }
        if (!privkey.key) {
            log0(0, 0, 0, "Failed to read/generate private key");
            exit(ERR_CRYPTO);
        }
        privkeylen = RSA_keylen(privkey.rsa);
    } else {
        if ((!strcmp(keyfile, "")) || (ecdsa_curve != 0)) {
            privkey.ec = gen_EC_key(ecdsa_curve, 0, keyfile);
        } else {
            privkey.ec = read_EC_key(keyfile);
        }
        if (!privkey.key) {
            log0(0, 0, 0, "Failed to read/generate private key");
            exit(ERR_CRYPTO);
        }
        privkeylen = ECDSA_siglen(privkey.ec);
    }
    if ((keyextype == KEYEX_ECDH_RSA) || (keyextype == KEYEX_ECDH_ECDSA)) {
        dhkey.ec = gen_EC_key(ecdh_curve, 1, NULL);
        if (!dhkey.key) {
            log0(0, 0, 0, "Failed to generate DH key");
            exit(ERR_CRYPTO);
        }
    }
}