Exemplo n.º 1
0
/**
 * @brief Get random bytes
 *
 * Make sure to always check the return code of this function!
 *
 * @param[in]  where    The buffer to fill with random bytes
 *
 * @param[in]  len      The size of the buffer to fill.
 *
 * @param[in]  strong   Use a strong or private RNG source.
 *
 * @return 1 on success, 0 on error.
 */
int ssh_get_random(void *where, int len, int strong)
{
#ifdef HAVE_OPENSSL_RAND_PRIV_BYTES
    if (strong) {
        /* Returns -1 when not supported, 0 on error, 1 on success */
        return !!RAND_priv_bytes(where, len);
    }
#else
    (void)strong;
#endif /* HAVE_RAND_PRIV_BYTES */

    /* Returns -1 when not supported, 0 on error, 1 on success */
    return !!RAND_bytes(where, len);
}
Exemplo n.º 2
0
/* Setup EVP_PKEY using public, private or generation */
static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
                      const unsigned char *p, int plen, ecx_key_op_t op)
{
    ECX_KEY *key = NULL;
    unsigned char *privkey, *pubkey;

    if (op != KEY_OP_KEYGEN) {
        if (palg != NULL) {
            int ptype;

            /* Algorithm parameters must be absent */
            X509_ALGOR_get0(NULL, &ptype, NULL, palg);
            if (ptype != V_ASN1_UNDEF) {
                ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
                return 0;
            }
        }

        if (p == NULL || plen != KEYLENID(id)) {
            ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
            return 0;
        }
    }

    key = OPENSSL_zalloc(sizeof(*key));
    if (key == NULL) {
        ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
        return 0;
    }
    pubkey = key->pubkey;

    if (op == KEY_OP_PUBLIC) {
        memcpy(pubkey, p, plen);
    } else {
        privkey = key->privkey = OPENSSL_secure_malloc(KEYLENID(id));
        if (privkey == NULL) {
            ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        if (op == KEY_OP_KEYGEN) {
            if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) {
                OPENSSL_secure_free(privkey);
                key->privkey = NULL;
                goto err;
            }
            if (id == EVP_PKEY_X25519) {
                privkey[0] &= 248;
                privkey[X25519_KEYLEN - 1] &= 127;
                privkey[X25519_KEYLEN - 1] |= 64;
            } else if (id == EVP_PKEY_X448) {
                privkey[0] &= 252;
                privkey[X448_KEYLEN - 1] |= 128;
            }
        } else {
            memcpy(privkey, p, KEYLENID(id));
        }
        switch (id) {
        case EVP_PKEY_X25519:
            X25519_public_from_private(pubkey, privkey);
            break;
        case EVP_PKEY_ED25519:
            ED25519_public_from_private(pubkey, privkey);
            break;
        case EVP_PKEY_X448:
            X448_public_from_private(pubkey, privkey);
            break;
        case EVP_PKEY_ED448:
            ED448_public_from_private(pubkey, privkey);
            break;
        }
    }

    EVP_PKEY_assign(pkey, id, key);
    return 1;
 err:
    OPENSSL_free(key);
    return 0;
}