isc_result_t dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) { isc_result_t result; REQUIRE(mctx != NULL && ectx != NULL); REQUIRE(dst_initialized == ISC_FALSE); dst__memory_pool = NULL; #ifdef OPENSSL UNUSED(mctx); /* * When using --with-openssl, there seems to be no good way of not * leaking memory due to the openssl error handling mechanism. * Avoid assertions by using a local memory context and not checking * for leaks on exit. Note: as there are leaks we cannot use * ISC_MEMFLAG_INTERNAL as it will free up memory still being used * by libcrypto. */ result = isc_mem_createx2(0, 0, default_memalloc, default_memfree, NULL, &dst__memory_pool, 0); if (result != ISC_R_SUCCESS) return (result); isc_mem_setdestroycheck(dst__memory_pool, ISC_FALSE); #else isc_mem_attach(mctx, &dst__memory_pool); #endif isc_entropy_attach(ectx, &dst_entropy_pool); dst_entropy_flags = eflags; dst_result_register(); memset(dst_t_func, 0, sizeof(dst_t_func)); RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5])); RETERR(dst__hmacsha1_init(&dst_t_func[DST_ALG_HMACSHA1])); RETERR(dst__hmacsha224_init(&dst_t_func[DST_ALG_HMACSHA224])); RETERR(dst__hmacsha256_init(&dst_t_func[DST_ALG_HMACSHA256])); RETERR(dst__hmacsha384_init(&dst_t_func[DST_ALG_HMACSHA384])); RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512])); #ifdef OPENSSL RETERR(dst__openssl_init()); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5])); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1])); #ifdef HAVE_OPENSSL_DSA RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA])); #endif RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH])); #endif /* OPENSSL */ #ifdef GSSAPI RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI])); #endif dst_initialized = ISC_TRUE; return (ISC_R_SUCCESS); out: dst_lib_destroy(); return (result); }
isc_result_t dns_tkeyctx_create(isc_mem_t *mctx, isc_entropy_t *ectx, dns_tkeyctx_t **tctxp) { dns_tkeyctx_t *tctx; REQUIRE(mctx != NULL); REQUIRE(ectx != NULL); REQUIRE(tctxp != NULL && *tctxp == NULL); tctx = isc_mem_get(mctx, sizeof(dns_tkeyctx_t)); if (tctx == NULL) return (ISC_R_NOMEMORY); tctx->mctx = NULL; isc_mem_attach(mctx, &tctx->mctx); tctx->ectx = NULL; isc_entropy_attach(ectx, &tctx->ectx); tctx->dhkey = NULL; tctx->domain = NULL; tctx->gsscred = NULL; *tctxp = tctx; return (ISC_R_SUCCESS); }
isc_result_t isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, unsigned int limit, isc_hash_t **hctxp) { isc_result_t result; isc_hash_t *hctx; size_t vlen; hash_random_t *rv; hash_accum_t overflow_limit; REQUIRE(mctx != NULL); REQUIRE(hctxp != NULL && *hctxp == NULL); /* * Overflow check. Since our implementation only does a modulo * operation at the last stage of hash calculation, the accumulator * must not overflow. */ overflow_limit = 1 << (((sizeof(hash_accum_t) - sizeof(hash_random_t))) * 8); if (overflow_limit < (limit + 1) * 0xff) return (ISC_R_RANGE); hctx = isc_mem_get(mctx, sizeof(isc_hash_t)); if (hctx == NULL) return (ISC_R_NOMEMORY); vlen = sizeof(hash_random_t) * (limit + 1); rv = isc_mem_get(mctx, vlen); if (rv == NULL) { result = ISC_R_NOMEMORY; goto errout; } /* * We need a lock. */ result = isc_mutex_init(&hctx->lock); if (result != ISC_R_SUCCESS) goto errout; /* * From here down, no failures will/can occur. */ hctx->magic = HASH_MAGIC; hctx->mctx = NULL; isc_mem_attach(mctx, &hctx->mctx); hctx->initialized = ISC_FALSE; result = isc_refcount_init(&hctx->refcnt, 1); if (result != ISC_R_SUCCESS) goto cleanup_lock; hctx->entropy = NULL; hctx->limit = limit; hctx->vectorlen = vlen; hctx->rndvector = rv; if (entropy != NULL) isc_entropy_attach(entropy, &hctx->entropy); *hctxp = hctx; return (ISC_R_SUCCESS); cleanup_lock: DESTROYLOCK(&hctx->lock); errout: isc_mem_put(mctx, hctx, sizeof(isc_hash_t)); if (rv != NULL) isc_mem_put(mctx, rv, vlen); return (result); }
isc_result_t dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, const char *engine, unsigned int eflags) { isc_result_t result; REQUIRE(mctx != NULL); UNUSED(ectx); REQUIRE(dst_initialized == ISC_FALSE); #if !defined(OPENSSL) && !defined(PKCS11CRYPTO) UNUSED(engine); #endif dst__memory_pool = NULL; #if defined(OPENSSL) UNUSED(mctx); /* * When using --with-openssl, there seems to be no good way of not * leaking memory due to the openssl error handling mechanism. * Avoid assertions by using a local memory context and not checking * for leaks on exit. Note: as there are leaks we cannot use * ISC_MEMFLAG_INTERNAL as it will free up memory still being used * by libcrypto. */ result = isc_mem_createx2(0, 0, default_memalloc, default_memfree, NULL, &dst__memory_pool, 0); if (result != ISC_R_SUCCESS) return (result); isc_mem_setname(dst__memory_pool, "dst", NULL); #ifndef OPENSSL_LEAKS isc_mem_setdestroycheck(dst__memory_pool, ISC_FALSE); #endif #else /* OPENSSL */ isc_mem_attach(mctx, &dst__memory_pool); #endif /* OPENSSL */ if (ectx != NULL) { isc_entropy_attach(ectx, &dst_entropy_pool); dst_entropy_flags = eflags; } dst_result_register(); memset(dst_t_func, 0, sizeof(dst_t_func)); RETERR(dst__hmacmd5_init(&dst_t_func[DST_ALG_HMACMD5])); RETERR(dst__hmacsha1_init(&dst_t_func[DST_ALG_HMACSHA1])); RETERR(dst__hmacsha224_init(&dst_t_func[DST_ALG_HMACSHA224])); RETERR(dst__hmacsha256_init(&dst_t_func[DST_ALG_HMACSHA256])); RETERR(dst__hmacsha384_init(&dst_t_func[DST_ALG_HMACSHA384])); RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512])); #ifdef OPENSSL RETERR(dst__openssl_init(engine)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5], DST_ALG_RSAMD5)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1], DST_ALG_RSASHA1)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1], DST_ALG_NSEC3RSASHA1)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA256], DST_ALG_RSASHA256)); RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA512], DST_ALG_RSASHA512)); #ifdef HAVE_OPENSSL_DSA RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA])); RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); #endif RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH])); #ifdef HAVE_OPENSSL_GOST RETERR(dst__opensslgost_init(&dst_t_func[DST_ALG_ECCGOST])); #endif #ifdef HAVE_OPENSSL_ECDSA RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); #endif #elif PKCS11CRYPTO RETERR(dst__pkcs11_init(mctx, engine)); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSAMD5])); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA1])); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1])); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA256])); RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA512])); RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_DSA])); RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); RETERR(dst__pkcs11dh_init(&dst_t_func[DST_ALG_DH])); #ifdef HAVE_PKCS11_ECDSA RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); #endif #ifdef HAVE_PKCS11_GOST RETERR(dst__pkcs11gost_init(&dst_t_func[DST_ALG_ECCGOST])); #endif #endif /* if OPENSSL, elif PKCS11CRYPTO */ #ifdef GSSAPI RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI])); #endif dst_initialized = ISC_TRUE; return (ISC_R_SUCCESS); out: /* avoid immediate crash! */ dst_initialized = ISC_TRUE; dst_lib_destroy(); return (result); }
int main(int argc, char **argv) { isc_mem_t *mctx; unsigned char buffer[512]; isc_entropy_t *ent; unsigned int returned; unsigned int flags; isc_result_t result; UNUSED(argc); UNUSED(argv); mctx = NULL; CHECK("isc_mem_create()", isc_mem_create(0, 0, &mctx)); ent = NULL; CHECK("isc_entropy_create()", isc_entropy_create(mctx, &ent)); isc_entropy_stats(ent, stderr); #if 1 CHECK("isc_entropy_createfilesource() 1", isc_entropy_createfilesource(ent, "/dev/random")); CHECK("isc_entropy_createfilesource() 2", isc_entropy_createfilesource(ent, "/dev/random")); #else CHECK("isc_entropy_createfilesource() 3", isc_entropy_createfilesource(ent, "/tmp/foo")); #endif fprintf(stderr, "Reading 32 bytes of GOOD random data only, partial OK\n"); flags = 0; flags |= ISC_ENTROPY_GOODONLY; flags |= ISC_ENTROPY_PARTIAL; result = isc_entropy_getdata(ent, buffer, 32, &returned, flags); if (result == ISC_R_NOENTROPY) { fprintf(stderr, "No entropy.\n"); goto any; } hex_dump("good data only:", buffer, returned); any: isc_entropy_stats(ent, stderr); CHECK("isc_entropy_getdata() pseudorandom", isc_entropy_getdata(ent, buffer, 128, NULL, 0)); hex_dump("pseudorandom data", buffer, 128); isc_entropy_stats(ent, stderr); flags = 0; flags |= ISC_ENTROPY_GOODONLY; flags |= ISC_ENTROPY_BLOCKING; result = isc_entropy_getdata(ent, buffer, sizeof(buffer), &returned, flags); CHECK("good data only, blocking mode", result); hex_dump("blocking mode data", buffer, sizeof(buffer)); { isc_entropy_t *entcopy1 = NULL; isc_entropy_t *entcopy2 = NULL; isc_entropy_t *entcopy3 = NULL; isc_entropy_attach(ent, &entcopy1); isc_entropy_attach(ent, &entcopy2); isc_entropy_attach(ent, &entcopy3); isc_entropy_stats(ent, stderr); isc_entropy_detach(&entcopy1); isc_entropy_detach(&entcopy2); isc_entropy_detach(&entcopy3); } isc_entropy_detach(&ent); isc_mem_stats(mctx, stderr); isc_mem_destroy(&mctx); return (0); }