You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by mi...@apache.org on 2019/06/24 21:33:04 UTC
svn commit: r1862027 - in /apr/apr-util/branches/1.7.x: ./ crypto/ include/
include/private/ test/
Author: minfrin
Date: Mon Jun 24 21:33:04 2019
New Revision: 1862027
URL: http://svn.apache.org/viewvc?rev=1862027&view=rev
Log:
Backport 1860984:
apr_crypto_prng: Move openssl specific code into apr_crypto_openssl.
Modified:
apr/apr-util/branches/1.7.x/ (props changed)
apr/apr-util/branches/1.7.x/crypto/ (props changed)
apr/apr-util/branches/1.7.x/crypto/apr_crypto.c
apr/apr-util/branches/1.7.x/crypto/apr_crypto_commoncrypto.c
apr/apr-util/branches/1.7.x/crypto/apr_crypto_nss.c
apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c
apr/apr-util/branches/1.7.x/crypto/apr_crypto_prng.c
apr/apr-util/branches/1.7.x/include/apr_crypto.h
apr/apr-util/branches/1.7.x/include/private/apr_crypto_internal.h
apr/apr-util/branches/1.7.x/test/testcrypto.c
Propchange: apr/apr-util/branches/1.7.x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jun 24 21:33:04 2019
@@ -1,4 +1,4 @@
-/apr/apr/trunk:781403,781409,784519,784592,789965,794508,917837-917838,982408-982409,998533,1086937,1127053,1127648,1128838,1129433,1133587,1207704,1210524,1211987,1214516,1308087,1308131,1308318,1327636,1340286,1346865,1357761,1357772,1357780,1357966,1357968,1357979,1358295,1358480,1361811,1362241,1362248,1362252,1362255,1363076,1369681,1370626,1371811,1371817,1371919,1371923,1382174,1389154,1389169,1390461,1390477,1402870,1402897,1402903,1402907,1406088,1422413,1425356,1426442,1426448,1438960,1449308,1449314,1460185,1460243-1460244,1462219,1462224,1484271,1493715,1495887,1495889,1496407,1516261,1523479,1529554,1531009,1541054,1543399,1544846,1618843,1619438,1625247,1626561,1648830,1711657,1722547,1728958,1728963,1747941,1751567,1751806,1751898,1752008,1763665,1763667,1763669,1763672-1763673,1763842-1763843,1765378,1772414,1778153,1781391,1782042,1782045,1788335,1789947,1809394,1811470,1820080,1825311,1833359,1833366,1833382,1833421,1833425-1833426,1833440,1833449-1833451,1833456,1
833525,1833599,1833993,1833995,1834022-1834024,1834551,1835392,1836017,1836229,1836231,1836438,1842824,1850087
+/apr/apr/trunk:781403,781409,784519,784592,789965,794508,917837-917838,982408-982409,998533,1086937,1127053,1127648,1128838,1129433,1133587,1207704,1210524,1211987,1214516,1308087,1308131,1308318,1327636,1340286,1346865,1357761,1357772,1357780,1357966,1357968,1357979,1358295,1358480,1361811,1362241,1362248,1362252,1362255,1363076,1369681,1370626,1371811,1371817,1371919,1371923,1382174,1389154,1389169,1390461,1390477,1402870,1402897,1402903,1402907,1406088,1422413,1425356,1426442,1426448,1438960,1449308,1449314,1460185,1460243-1460244,1462219,1462224,1484271,1493715,1495887,1495889,1496407,1516261,1523479,1529554,1531009,1541054,1543399,1544846,1618843,1619438,1625247,1626561,1648830,1711657,1722547,1728958,1728963,1747941,1751567,1751806,1751898,1752008,1763665,1763667,1763669,1763672-1763673,1763842-1763843,1765378,1772414,1778153,1781391,1782042,1782045,1788335,1789947,1809394,1811470,1820080,1825311,1833359,1833366,1833382,1833421,1833425-1833426,1833440,1833449-1833451,1833456,1
833525,1833599,1833993,1833995,1834022-1834024,1834551,1835392,1836017,1836229,1836231,1836438,1842824,1850087,1860984
/apr/apr-util/branches/1.3.x:896410,1154885
/apr/apr-util/branches/1.4.x:1126217,1211211,1211219,1211223,1211330
/apr/apr-util/branches/1.5.x:1757430
Propchange: apr/apr-util/branches/1.7.x/crypto/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Jun 24 21:33:04 2019
@@ -1,4 +1,4 @@
-/apr/apr/trunk/crypto:781403,781409,784519,784592,789965,794508,917837-917838,982408-982409,998533,1086937,1127053,1127648,1128838,1129433,1133587,1207704,1210524,1211987,1214516,1308087,1308131,1308318,1327636,1340286,1346865,1357761,1357772,1357780,1357966,1357968,1357979,1358295,1358480,1361811,1362241,1362248,1362252,1362255,1363076,1369681,1370626,1371811,1371817,1371919,1371923,1382174,1389154,1389169,1390461,1390477,1394552,1402870,1402897,1402903,1402907,1406088,1422413,1425356,1426442,1426448,1438960,1449308,1449314,1460185,1460243-1460244,1462219,1462224,1484271,1493715,1495887,1495889,1496407,1516261,1523479,1529554,1531009,1541054,1543399,1544846,1618843,1619438,1625247,1626561,1648830,1711657,1722547,1728958,1728963,1747941,1751806,1763665,1763667,1763669,1763672,1763842,1772414,1781391,1836438
+/apr/apr/trunk/crypto:781403,781409,784519,784592,789965,794508,917837-917838,982408-982409,998533,1086937,1127053,1127648,1128838,1129433,1133587,1207704,1210524,1211987,1214516,1308087,1308131,1308318,1327636,1340286,1346865,1357761,1357772,1357780,1357966,1357968,1357979,1358295,1358480,1361811,1362241,1362248,1362252,1362255,1363076,1369681,1370626,1371811,1371817,1371919,1371923,1382174,1389154,1389169,1390461,1390477,1394552,1402870,1402897,1402903,1402907,1406088,1422413,1425356,1426442,1426448,1438960,1449308,1449314,1460185,1460243-1460244,1462219,1462224,1484271,1493715,1495887,1495889,1496407,1516261,1523479,1529554,1531009,1541054,1543399,1544846,1618843,1619438,1625247,1626561,1648830,1711657,1722547,1728958,1728963,1747941,1751806,1763665,1763667,1763669,1763672,1763842,1772414,1781391,1836438,1860984
/apr/apr-util/branches/1.3.x/crypto:896410,1154885
/apr/apr-util/branches/1.4.x/crypto:1126217,1211211,1211219,1211223,1211330
/apr/apr-util/trunk/crypto:731033-731034,731225,731236,731291,731293,731379,743986,744009,745771,747612,747623,747630,1626561
Modified: apr/apr-util/branches/1.7.x/crypto/apr_crypto.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/crypto/apr_crypto.c?rev=1862027&r1=1862026&r2=1862027&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/crypto/apr_crypto.c (original)
+++ apr/apr-util/branches/1.7.x/crypto/apr_crypto.c Mon Jun 24 21:33:04 2019
@@ -97,10 +97,6 @@ static apr_status_t apr_crypto_term(void
APU_DECLARE(apr_status_t) apr_crypto_init(apr_pool_t *pool)
{
apr_pool_t *rootp;
-#if APU_HAVE_CRYPTO_PRNG
- apr_status_t rv;
- int flags = 0;
-#endif
if (drivers != NULL) {
return APR_SUCCESS;
@@ -123,19 +119,6 @@ APU_DECLARE(apr_status_t) apr_crypto_ini
apr_pool_cleanup_register(rootp, NULL, apr_crypto_term,
apr_pool_cleanup_null);
-#if APU_HAVE_CRYPTO_PRNG
- /* apr_crypto_prng_init() may already have been called with
- * non-default parameters, so ignore APR_EREINIT.
- */
-#if APR_HAS_THREADS
- flags = APR_CRYPTO_PRNG_PER_THREAD;
-#endif
- rv = apr_crypto_prng_init(pool, 0, NULL, flags);
- if (rv != APR_SUCCESS && rv != APR_EREINIT) {
- return rv;
- }
-#endif
-
return APR_SUCCESS;
}
Modified: apr/apr-util/branches/1.7.x/crypto/apr_crypto_commoncrypto.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/crypto/apr_crypto_commoncrypto.c?rev=1862027&r1=1862026&r2=1862027&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/crypto/apr_crypto_commoncrypto.c (original)
+++ apr/apr-util/branches/1.7.x/crypto/apr_crypto_commoncrypto.c Mon Jun 24 21:33:04 2019
@@ -1444,20 +1444,37 @@ static apr_status_t crypto_digest(
return status;
}
+static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
+ apr_crypto_t *f, apr_crypto_cipher_e cipher, apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
+void cprng_stream_ctx_free(cprng_stream_ctx_t *sctx)
+{
+}
+
+static apr_status_t cprng_stream_ctx_bytes(cprng_stream_ctx_t **pctx,
+ unsigned char *key, unsigned char *to, apr_size_t n, const unsigned char *z)
+{
+ return APR_ENOTIMPL;
+}
+
/**
* OSX Common Crypto module.
*/
APU_MODULE_DECLARE_DATA const apr_crypto_driver_t apr_crypto_commoncrypto_driver =
{
"commoncrypto", crypto_init, crypto_make,
- crypto_get_block_key_digests, crypto_get_block_key_types,
- crypto_get_block_key_modes, crypto_passphrase,
- crypto_block_encrypt_init, crypto_block_encrypt,
- crypto_block_encrypt_finish, crypto_block_decrypt_init,
- crypto_block_decrypt, crypto_block_decrypt_finish,
- crypto_digest_init, crypto_digest_update, crypto_digest_final,
- crypto_digest, crypto_block_cleanup, crypto_digest_cleanup,
- crypto_cleanup, crypto_shutdown, crypto_error, crypto_key
+ crypto_get_block_key_digests, crypto_get_block_key_types,
+ crypto_get_block_key_modes, crypto_passphrase,
+ crypto_block_encrypt_init, crypto_block_encrypt,
+ crypto_block_encrypt_finish, crypto_block_decrypt_init,
+ crypto_block_decrypt, crypto_block_decrypt_finish,
+ crypto_digest_init, crypto_digest_update, crypto_digest_final,
+ crypto_digest, crypto_block_cleanup, crypto_digest_cleanup,
+ crypto_cleanup, crypto_shutdown, crypto_error, crypto_key,
+ cprng_stream_ctx_make, cprng_stream_ctx_free, cprng_stream_ctx_bytes
};
#endif
Modified: apr/apr-util/branches/1.7.x/crypto/apr_crypto_nss.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/crypto/apr_crypto_nss.c?rev=1862027&r1=1862026&r2=1862027&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/crypto/apr_crypto_nss.c (original)
+++ apr/apr-util/branches/1.7.x/crypto/apr_crypto_nss.c Mon Jun 24 21:33:04 2019
@@ -1621,6 +1621,22 @@ static apr_status_t crypto_digest(
return status;
}
+static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
+ apr_crypto_t *f, apr_crypto_cipher_e cipher, apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
+void cprng_stream_ctx_free(cprng_stream_ctx_t *sctx)
+{
+}
+
+static apr_status_t cprng_stream_ctx_bytes(cprng_stream_ctx_t **pctx,
+ unsigned char *key, unsigned char *to, apr_size_t n, const unsigned char *z)
+{
+ return APR_ENOTIMPL;
+}
+
/**
* NSS module.
*/
@@ -1632,7 +1648,7 @@ APU_MODULE_DECLARE_DATA const apr_crypto
crypto_block_decrypt, crypto_block_decrypt_finish,
crypto_digest_init, crypto_digest_update, crypto_digest_final, crypto_digest,
crypto_block_cleanup, crypto_digest_cleanup, crypto_cleanup, crypto_shutdown, crypto_error,
- crypto_key
+ crypto_key, cprng_stream_ctx_make, cprng_stream_ctx_free, cprng_stream_ctx_bytes
};
#endif
Modified: apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c?rev=1862027&r1=1862026&r2=1862027&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c (original)
+++ apr/apr-util/branches/1.7.x/crypto/apr_crypto_openssl.c Mon Jun 24 21:33:04 2019
@@ -33,6 +33,7 @@
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/engine.h>
+#include <openssl/obj_mac.h> /* for NID_* */
#define LOG_PREFIX "apr_crypto_openssl: "
@@ -103,6 +104,10 @@ struct apr_crypto_digest_t {
int digestSize;
};
+struct cprng_stream_ctx_t {
+ EVP_CIPHER_CTX *ctx;
+};
+
static struct apr_crypto_block_key_digest_t key_digests[] =
{
{ APR_CRYPTO_DIGEST_MD5, 16, 64 },
@@ -1500,6 +1505,124 @@ static apr_status_t crypto_digest(
return status;
}
+static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
+ apr_crypto_t *f, apr_crypto_cipher_e cipher, apr_pool_t *pool)
+{
+ cprng_stream_ctx_t *sctx;
+ EVP_CIPHER_CTX *ctx;
+ const EVP_CIPHER *ecipher;
+
+ if (pool) {
+ *psctx = sctx = apr_palloc(pool, sizeof(cprng_stream_ctx_t));
+ }
+ else {
+ *psctx = sctx = malloc(sizeof(cprng_stream_ctx_t));
+ }
+ if (!sctx) {
+ return APR_ENOMEM;
+ }
+
+ sctx->ctx = ctx = EVP_CIPHER_CTX_new();
+ if (!ctx) {
+ return APR_ENOMEM;
+ }
+
+ /* We only handle Chacha20 and AES256-CTR stream ciphers, for now.
+ * AES256-CTR should be in any openssl version of this century but is used
+ * only if Chacha20 is missing (openssl < 1.1). This is because Chacha20 is
+ * fast (enough) in software and timing attacks safe, though AES256-CTR can
+ * be faster and constant-time but only when the CPU (aesni) or some crypto
+ * hardware are in place.
+ */
+ switch (cipher) {
+ case APR_CRYPTO_CIPHER_AUTO: {
+#if defined(NID_chacha20)
+ ecipher = EVP_chacha20();
+#elif defined(NID_aes_256_ctr)
+ ecipher = EVP_aes_256_ctr();
+#else
+ return APR_ENOCIPHER;
+#endif
+ }
+ case APR_CRYPTO_CIPHER_AES_256_CTR: {
+#if defined(NID_aes_256_ctr)
+ ecipher = EVP_aes_256_ctr();
+ break;
+#else
+ return APR_ENOCIPHER;
+#endif
+ }
+ case APR_CRYPTO_CIPHER_CHACHA20_CTR: {
+#if defined(NID_chacha20)
+ ecipher = EVP_chacha20();
+ break;
+#else
+ return APR_ENOCIPHER;
+#endif
+ }
+ default: {
+ return APR_ENOCIPHER;
+ }
+ }
+
+ if (EVP_EncryptInit_ex(ctx, ecipher, f->config->engine, NULL, NULL) <= 0) {
+ EVP_CIPHER_CTX_free(ctx);
+ return APR_ENOMEM;
+ }
+
+ return APR_SUCCESS;
+}
+
+void cprng_stream_ctx_free(cprng_stream_ctx_t *sctx)
+{
+ EVP_CIPHER_CTX_free(sctx->ctx);
+}
+
+static APR_INLINE
+void cprng_stream_setkey(cprng_stream_ctx_t *sctx,
+ const unsigned char *key,
+ const unsigned char *iv)
+{
+#if defined(NID_chacha20)
+ /* With CHACHA20, iv=NULL is the same as zeros but it's faster
+ * to (re-)init; use that for efficiency.
+ */
+ EVP_EncryptInit_ex(sctx->ctx, NULL, NULL, key, NULL);
+#else
+ /* With AES256-CTR, iv=NULL seems to peek up and random one (for
+ * the initial CTR), while we can live with zeros (fixed CTR);
+ * efficiency still.
+ */
+ EVP_EncryptInit_ex(sctx->ctx, NULL, NULL, key, iv);
+#endif
+}
+
+static apr_status_t cprng_stream_ctx_bytes(cprng_stream_ctx_t **pctx,
+ unsigned char *key, unsigned char *to, apr_size_t n, const unsigned char *z)
+{
+ cprng_stream_ctx_t *sctx = *pctx;
+ int len;
+
+ /* We never encrypt twice with the same key, so no IV is needed (can
+ * be zeros). When EVP_EncryptInit() is called multiple times it clears
+ * its previous resources appropriately, and since we don't want the key
+ * and its keystream to reside in memory at the same time, we have to
+ * EVP_EncryptInit() twice: firstly to set the key and then finally to
+ * overwrite the key (with zeros) after the keystream is produced.
+ * As for EVP_EncryptFinish(), we don't need it either because padding
+ * is disabled (irrelevant for a stream cipher).
+ */
+ cprng_stream_setkey(sctx, key, z);
+ EVP_CIPHER_CTX_set_padding(sctx->ctx, 0);
+ EVP_EncryptUpdate(sctx->ctx, key, &len, z, CPRNG_KEY_SIZE);
+ if (n) {
+ EVP_EncryptUpdate(sctx->ctx, to, &len, z, n);
+ }
+ cprng_stream_setkey(sctx, z, z);
+
+ return APR_SUCCESS;
+}
+
/**
* OpenSSL module.
*/
@@ -1511,7 +1634,7 @@ APU_MODULE_DECLARE_DATA const apr_crypto
crypto_block_decrypt, crypto_block_decrypt_finish,
crypto_digest_init, crypto_digest_update, crypto_digest_final, crypto_digest,
crypto_block_cleanup, crypto_digest_cleanup, crypto_cleanup, crypto_shutdown, crypto_error,
- crypto_key
+ crypto_key, cprng_stream_ctx_make, cprng_stream_ctx_free, cprng_stream_ctx_bytes
};
#endif
Modified: apr/apr-util/branches/1.7.x/crypto/apr_crypto_prng.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/crypto/apr_crypto_prng.c?rev=1862027&r1=1862026&r2=1862027&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/crypto/apr_crypto_prng.c (original)
+++ apr/apr-util/branches/1.7.x/crypto/apr_crypto_prng.c Mon Jun 24 21:33:04 2019
@@ -41,6 +41,7 @@
#include "apu.h"
#include "apr_crypto.h"
+#include "apr_crypto_internal.h"
#if APU_HAVE_CRYPTO
#if APU_HAVE_CRYPTO_PRNG
@@ -53,8 +54,6 @@
#include <stdlib.h> /* for malloc() */
-#define CPRNG_KEY_SIZE 32
-
/* Be consistent with the .h (the seed is xor-ed with key on reseed). */
#if CPRNG_KEY_SIZE != APR_CRYPTO_PRNG_SEED_SIZE
#error apr_crypto_prng handles stream ciphers with 256bit keys only
@@ -63,113 +62,21 @@
#define CPRNG_BUF_SIZE_MIN (CPRNG_KEY_SIZE * (8 - 1))
#define CPRNG_BUF_SIZE_DEF (CPRNG_KEY_SIZE * (24 - 1))
-#if APU_HAVE_OPENSSL
-
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-
-/* We only handle Chacha20 and AES256-CTR stream ciphers, for now.
- * AES256-CTR should be in any openssl version of this century but is used
- * only if Chacha20 is missing (openssl < 1.1). This is because Chacha20 is
- * fast (enough) in software and timing attacks safe, though AES256-CTR can
- * be faster and constant-time but only when the CPU (aesni) or some crypto
- * hardware are in the place.
- */
-#include <openssl/obj_mac.h> /* for NID_* */
-#if !defined(NID_chacha20) && !defined(NID_aes_256_ctr)
-/* XXX: APU_HAVE_CRYPTO_PRNG && APU_HAVE_OPENSSL shoudn't be defined! */
-#error apr_crypto_prng needs OpenSSL implementation for Chacha20 or AES256-CTR
-#endif
-
-typedef EVP_CIPHER_CTX cprng_stream_ctx_t;
-
-static apr_status_t cprng_lib_init(apr_pool_t *pool)
-{
- return apr_crypto_lib_init("openssl", NULL, NULL, pool);
-}
-
-static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **pctx)
-{
- EVP_CIPHER_CTX *ctx;
- const EVP_CIPHER *cipher;
-
- ctx = EVP_CIPHER_CTX_new();
- if (!ctx) {
- return APR_ENOMEM;
- }
-
-#if defined(NID_chacha20)
- cipher = EVP_chacha20();
-#else
- cipher = EVP_aes_256_ctr();
-#endif
- if (EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL) <= 0) {
- EVP_CIPHER_CTX_free(ctx);
- return APR_ENOMEM;
- }
-
- *pctx = ctx;
- return APR_SUCCESS;
-}
-
-static APR_INLINE
-void cprng_stream_ctx_free(cprng_stream_ctx_t *ctx)
-{
- EVP_CIPHER_CTX_free(ctx);
-}
-
-static APR_INLINE
-apr_status_t cprng_stream_ctx_bytes(cprng_stream_ctx_t **pctx,
- unsigned char *key, unsigned char *to,
- apr_size_t n, const unsigned char *z)
-{
- cprng_stream_ctx_t *ctx = *pctx;
- int len;
-
- /* Can be called for rekeying (key != NULL), streaming more bytes
- * with the current key (n != 0), or both successively in a one go.
- */
- if (key) {
- /* We never encrypt twice with the same key, so we can use an
- * all zeros IV. Also EVP_EncryptInit() can be called multiple
- * times and it will recycle its previous/replaced resources by
- * itself, so since padding is disabled/irrelevant too we don't
- * need EVP_EncryptFinish() after each call or before rekeying.
- */
-#if defined(NID_chacha20)
- /* With CHACHA20, iv=NULL is the same as zeros but it's faster
- * to (re-)init; use that for efficiency.
- */
- EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL);
-#else
- /* With AES256-CTR, iv=NULL seems to peek up and random one (for
- * the initial CTR), while we can live with zeros (fixed CTR);
- * efficiency still.
- */
- EVP_EncryptInit_ex(ctx, NULL, NULL, key, z);
-#endif
- EVP_CIPHER_CTX_set_padding(ctx, 0);
-
- memset(key, 0, CPRNG_KEY_SIZE);
- EVP_EncryptUpdate(ctx, key, &len, key, CPRNG_KEY_SIZE);
- }
- if (n) {
- EVP_EncryptUpdate(ctx, to, &len, z, n);
- }
-
- return APR_SUCCESS;
-}
-
-#else /* APU_HAVE_OPENSSL */
-
-/* XXX: APU_HAVE_CRYPTO_PRNG shoudn't be defined! */
-#error apr_crypto_prng implemented with OpenSSL only for now
+#define APR_TYPEDEF_STRUCT(type, incompletion) \
+struct type { \
+ incompletion \
+ void *unk[]; \
+};
-#endif /* APU_HAVE_OPENSSL */
+APR_TYPEDEF_STRUCT(apr_crypto_t,
+ apr_pool_t *pool;
+ apr_crypto_driver_t *provider;
+)
struct apr_crypto_prng_t {
APR_RING_ENTRY(apr_crypto_prng_t) link;
apr_pool_t *pool;
+ apr_crypto_t *crypto;
cprng_stream_ctx_t *ctx;
#if APR_HAS_THREADS
apr_thread_mutex_t *mutex;
@@ -177,6 +84,7 @@ struct apr_crypto_prng_t {
unsigned char *key, *buf;
apr_size_t len, pos;
int flags;
+ apr_crypto_cipher_e cipher;
};
static apr_crypto_prng_t *cprng_global = NULL;
@@ -219,10 +127,8 @@ static void cprng_thread_destroy(void *c
#define cprng_ring_unlock()
#endif /* !APR_HAS_THREADS */
-APU_DECLARE(apr_status_t) apr_crypto_prng_init(apr_pool_t *pool,
- apr_size_t bufsize,
- const unsigned char seed[],
- int flags)
+APU_DECLARE(apr_status_t) apr_crypto_prng_init(apr_pool_t *pool, apr_crypto_t *crypto,
+ apr_crypto_cipher_e cipher, apr_size_t bufsize, const unsigned char seed[], int flags)
{
apr_status_t rv;
@@ -230,11 +136,6 @@ APU_DECLARE(apr_status_t) apr_crypto_prn
return APR_EREINIT;
}
- rv = cprng_lib_init(pool);
- if (rv != APR_SUCCESS && rv != APR_EREINIT) {
- return rv;
- }
-
if (flags & APR_CRYPTO_PRNG_PER_THREAD) {
#if !APR_HAS_THREADS
return APR_ENOTIMPL;
@@ -266,7 +167,8 @@ APU_DECLARE(apr_status_t) apr_crypto_prn
flags = (flags | APR_CRYPTO_PRNG_LOCKED) & ~APR_CRYPTO_PRNG_PER_THREAD;
#endif
- return apr_crypto_prng_create(&cprng_global, bufsize, flags, seed, pool);
+ return apr_crypto_prng_create(&cprng_global, crypto, cipher, bufsize, flags,
+ seed, pool);
}
APU_DECLARE(apr_status_t) apr_crypto_prng_term(void)
@@ -298,7 +200,7 @@ APU_DECLARE(apr_status_t) apr_crypto_ran
apr_crypto_prng_t *cprng;
void *private = NULL;
- if (!cprng_thread_key) {
+ if (!cprng_thread_key || !cprng_global) {
return APR_EINIT;
}
@@ -309,8 +211,8 @@ APU_DECLARE(apr_status_t) apr_crypto_ran
cprng = private;
if (!cprng) {
- rv = apr_crypto_prng_create(&cprng, 0, APR_CRYPTO_PRNG_PER_THREAD,
- NULL, NULL);
+ rv = apr_crypto_prng_create(&cprng, cprng_global->crypto, cprng_global->cipher, 0,
+ APR_CRYPTO_PRNG_PER_THREAD, NULL, NULL);
if (rv != APR_SUCCESS) {
return rv;
}
@@ -344,7 +246,7 @@ static apr_status_t cprng_cleanup(void *
}
if (cprng->ctx) {
- cprng_stream_ctx_free(cprng->ctx);
+ cprng->crypto->provider->cprng_stream_ctx_free(cprng->ctx);
}
if (cprng->key) {
@@ -360,9 +262,8 @@ static apr_status_t cprng_cleanup(void *
}
APU_DECLARE(apr_status_t) apr_crypto_prng_create(apr_crypto_prng_t **pcprng,
- apr_size_t bufsize, int flags,
- const unsigned char seed[],
- apr_pool_t *pool)
+ apr_crypto_t *crypto, apr_crypto_cipher_e cipher, apr_size_t bufsize, int flags,
+ const unsigned char seed[], apr_pool_t *pool)
{
apr_status_t rv;
apr_crypto_prng_t *cprng;
@@ -394,6 +295,7 @@ APU_DECLARE(apr_status_t) apr_crypto_prn
if (!cprng) {
return APR_ENOMEM;
}
+ cprng->cipher = cipher;
cprng->flags = flags;
cprng->pool = pool;
@@ -420,7 +322,40 @@ APU_DECLARE(apr_status_t) apr_crypto_prn
cprng->buf = cprng->key + CPRNG_KEY_SIZE;
cprng->len = bufsize;
- rv = cprng_stream_ctx_make(&cprng->ctx);
+ if (crypto) {
+ cprng->crypto = crypto;
+ }
+ else if (cprng_global && cprng_global->crypto) {
+ cprng->crypto = cprng_global->crypto;
+ }
+ else {
+ const apr_crypto_driver_t *driver = NULL;
+ if (!pool) {
+ return APR_EINVAL;
+ }
+
+ rv = apr_crypto_init(pool);
+ if (rv != APR_SUCCESS) {
+ cprng_cleanup(cprng);
+ return rv;
+ }
+
+ rv = apr_crypto_get_driver(&driver, "openssl",
+ NULL, NULL, pool);
+ if (rv != APR_SUCCESS) {
+ cprng_cleanup(cprng);
+ return rv;
+ }
+
+ rv = apr_crypto_make(&cprng->crypto, driver, NULL, pool);
+ if (rv != APR_SUCCESS) {
+ cprng_cleanup(cprng);
+ return rv;
+ }
+ }
+
+ rv = cprng->crypto->provider->cprng_stream_ctx_make(&cprng->ctx,
+ cprng->crypto, cprng->cipher, pool);
if (rv != APR_SUCCESS) {
cprng_cleanup(cprng);
return rv;
@@ -479,7 +414,8 @@ static apr_status_t cprng_stream_bytes(a
{
apr_status_t rv;
- rv = cprng_stream_ctx_bytes(&cprng->ctx, key, to, len, cprng->buf);
+ rv = cprng->crypto->provider->cprng_stream_ctx_bytes(&cprng->ctx,
+ cprng->key, to, len, cprng->buf);
if (rv != APR_SUCCESS && len) {
apr_crypto_memzero(to, len);
}
Modified: apr/apr-util/branches/1.7.x/include/apr_crypto.h
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/include/apr_crypto.h?rev=1862027&r1=1862026&r2=1862027&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/include/apr_crypto.h (original)
+++ apr/apr-util/branches/1.7.x/include/apr_crypto.h Mon Jun 24 21:33:04 2019
@@ -159,6 +159,16 @@ typedef struct apr_crypto_block_key_dige
} apr_crypto_block_key_digest_t;
/**
+ * Types of ciphers supported by the apr_
+ */
+typedef enum
+{
+ APR_CRYPTO_CIPHER_AUTO, /** Choose the recommended cipher / autodetect the cipher */
+ APR_CRYPTO_CIPHER_AES_256_CTR, /** AES 256 - CTR mode */
+ APR_CRYPTO_CIPHER_CHACHA20_CTR, /** ChaCha20 - CTR mode */
+} apr_crypto_cipher_e;
+
+/**
* Structure representing a backend crypto driver.
*
* This structure is created with apr_crypto_get_driver().
@@ -1008,6 +1018,9 @@ typedef struct apr_crypto_prng_t apr_cry
* @brief Perform global initialisation. Call once only.
*
* @param pool Used to allocate memory and register cleanups
+ * @param crypto The crypto context to use. If NULL, one will be created from
+ * the recommended crypto implementation.
+ * @param cipher The cipher to use.
* @param bufsize The size of the buffer used to cache upcoming random bytes.
* @param seed A custom seed of \ref APR_CRYPTO_PRNG_SEED_SIZE bytes,
* or NULL for the seed to be gathered from system entropy.
@@ -1016,10 +1029,9 @@ typedef struct apr_crypto_prng_t apr_cry
* @return APR_EREINIT if called more than once,
* any system error (APR_ENOMEM, ...).
*/
-APU_DECLARE(apr_status_t) apr_crypto_prng_init(apr_pool_t *pool,
- apr_size_t bufsize,
- const unsigned char seed[],
- int flags);
+APU_DECLARE(apr_status_t) apr_crypto_prng_init(apr_pool_t *pool, apr_crypto_t *crypto,
+ apr_crypto_cipher_e cipher, apr_size_t bufsize, const unsigned char seed[], int flags);
+
/**
* @brief Terminate global initialisation if needed, before automatic cleanups.
*
@@ -1049,13 +1061,16 @@ APU_DECLARE(apr_status_t) apr_crypto_ran
* any system error (APR_ENOMEM, ...).
*/
APU_DECLARE(apr_status_t) apr_crypto_random_thread_bytes(void *buf,
- apr_size_t len);
+ apr_size_t len);
#endif
/**
* @brief Create a standalone CPRNG.
*
* @param pcprng The CPRNG created.
+ * @param crypto The crypto context to use. If NULL, one will be created from
+ * the recommended crypto implementation.
+ * @param cipher The cipher to use.
* @param bufsize The size of the buffer used to cache upcoming random bytes.
* @param flags \ref APR_CRYPTO_PRNG_LOCKED to control concurrent accesses,
* or zero.
@@ -1068,12 +1083,12 @@ APU_DECLARE(apr_status_t) apr_crypto_ran
* \ref apr_crypto_prng_destroy() or some memory would leak.
* @return APR_EINVAL if \ref bufsize is too large or flags are unknown,
* APR_ENOTIMPL if \ref APR_CRYPTO_PRNG_LOCKED with !APR_HAS_THREADS,
+ * APR_ENOCIPHER if neither Chacha20 nor AES-256-CTR are available,
* any system error (APR_ENOMEM, ...).
*/
APU_DECLARE(apr_status_t) apr_crypto_prng_create(apr_crypto_prng_t **pcprng,
- apr_size_t bufsize, int flags,
- const unsigned char seed[],
- apr_pool_t *pool);
+ apr_crypto_t *crypto, apr_crypto_cipher_e cipher, apr_size_t bufsize,
+ int flags, const unsigned char seed[], apr_pool_t *pool);
/**
* @brief Destroy a standalone CPRNG.
Modified: apr/apr-util/branches/1.7.x/include/private/apr_crypto_internal.h
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/include/private/apr_crypto_internal.h?rev=1862027&r1=1862026&r2=1862027&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/include/private/apr_crypto_internal.h (original)
+++ apr/apr-util/branches/1.7.x/include/private/apr_crypto_internal.h Mon Jun 24 21:33:04 2019
@@ -27,6 +27,16 @@ extern "C" {
#if APU_HAVE_CRYPTO
+/**
+ * Structure representing the streaming context for the CPRNG.
+ */
+typedef struct cprng_stream_ctx_t cprng_stream_ctx_t;
+
+/**
+ * Key size for the CPRNG.
+ */
+#define CPRNG_KEY_SIZE 32
+
struct apr_crypto_driver_t {
/** name */
@@ -363,6 +373,33 @@ struct apr_crypto_driver_t {
apr_status_t (*key)(apr_crypto_key_t **key, const apr_crypto_key_rec_t *rec,
const apr_crypto_t *f, apr_pool_t *p);
+ /**
+ * @brief Create the context for encrypting the CPRNG stream.
+ * @param pctx The pointer where the context will be returned.
+ * @param f The crypto context to use.
+ * @param cipher The cipher to use.
+ * @param pool The pool to use.
+ */
+ apr_status_t (*cprng_stream_ctx_make)(cprng_stream_ctx_t **pctx, apr_crypto_t *f,
+ apr_crypto_cipher_e cipher, apr_pool_t *pool);
+
+ /**
+ * @brief Free the context for encrypting the CPRNG stream.
+ * @param ctx The context to free.
+ */
+ void (*cprng_stream_ctx_free)(cprng_stream_ctx_t *ctx);
+
+ /**
+ * @brief Return further encrypted bytes, rekeying as necessary.
+ * @param pctx The context.
+ * @param key The key to use while rekeying.
+ * @param to Encrypted bytes are written here.
+ * @param n Length of encrypted bytes.
+ * @param z The IV to use.
+ */
+ apr_status_t (*cprng_stream_ctx_bytes)(cprng_stream_ctx_t **pctx, unsigned char *key,
+ unsigned char *to, apr_size_t n, const unsigned char *z);
+
};
#if APU_HAVE_OPENSSL
Modified: apr/apr-util/branches/1.7.x/test/testcrypto.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.7.x/test/testcrypto.c?rev=1862027&r1=1862026&r2=1862027&view=diff
==============================================================================
--- apr/apr-util/branches/1.7.x/test/testcrypto.c (original)
+++ apr/apr-util/branches/1.7.x/test/testcrypto.c Mon Jun 24 21:33:04 2019
@@ -2365,10 +2365,6 @@ static void test_crypto_equals(abts_case
}
#if APU_HAVE_CRYPTO_PRNG
-#if APU_HAVE_OPENSSL
-#include <openssl/obj_mac.h> /* for NID_* */
-#endif
-#if defined(NID_chacha20)
/*
* KAT for CHACHA20:
* # iv=$(printf "%.32d" 0)
@@ -2380,7 +2376,7 @@ static void test_crypto_equals(abts_case
* -in /dev/zero -K $key -iv $iv \
* | xxd -l128 -c8 -i
*/
-static const unsigned char test_PRNG_kat0[128] = {
+static const unsigned char test_PRNG_kat0_chacha20[128] = {
0xb0, 0xfd, 0x14, 0xff, 0x96, 0xa0, 0xbd, 0xa1,
0x54, 0xc3, 0x29, 0x08, 0x2c, 0x9c, 0x65, 0x33,
0xbb, 0x4c, 0x94, 0x73, 0xbf, 0x5d, 0xde, 0x13,
@@ -2398,7 +2394,7 @@ static const unsigned char test_PRNG_kat
0xb8, 0x79, 0xb5, 0x57, 0x47, 0x97, 0xa1, 0xb7,
0x3d, 0xce, 0x7c, 0xd0, 0x9f, 0x24, 0x51, 0x01
};
-#else
+
/*
* KAT for AES256-CTR:
* # iv=$(printf "%.32d" 0)
@@ -2410,7 +2406,7 @@ static const unsigned char test_PRNG_kat
* -in /dev/zero -K $key -iv $iv \
* | xxd -l128 -c8 -i
*/
-static const unsigned char test_PRNG_kat0[128] = {
+static const unsigned char test_PRNG_kat0_aes256[128] = {
0x79, 0x04, 0x2a, 0x33, 0xfa, 0x41, 0x1a, 0x37,
0x97, 0x3a, 0xec, 0xa0, 0xfc, 0xde, 0x6b, 0x2b,
0x16, 0xa4, 0x5f, 0xa1, 0x2a, 0xe3, 0xf5, 0x4c,
@@ -2428,26 +2424,49 @@ static const unsigned char test_PRNG_kat
0xc5, 0x0c, 0xe6, 0x71, 0x42, 0xbf, 0x81, 0xb0,
0xd1, 0x59, 0x28, 0xa1, 0x04, 0xe9, 0x8d, 0xad
};
-#endif
-static void test_crypto_prng(abts_case *tc, void *data)
+static void test_crypto_prng(abts_case *tc, apr_crypto_cipher_e cipher, const unsigned char *test_PRNG_kat0)
{
unsigned char randbytes[128], seed[APR_CRYPTO_PRNG_SEED_SIZE];
apr_crypto_prng_t *cprng = NULL;
apr_pool_t *pool = NULL;
apr_status_t rv;
int i;
+ int flags = 0;
rv = apr_pool_create(&pool, NULL);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
ABTS_PTR_NOTNULL(tc, pool);
+#if APR_HAS_THREADS
+ flags = APR_CRYPTO_PRNG_PER_THREAD;
+#endif
+ rv = apr_crypto_prng_init(pool, NULL, cipher, 0, NULL, flags);
+
+ if (APR_ENOCIPHER == rv) {
+ apr_pool_destroy(pool);
+ return;
+ }
+
+ ABTS_ASSERT(tc, "apr_crypto_prng_init returned APR_EREINIT", rv != APR_EREINIT);
+ ABTS_ASSERT(tc, "apr_crypto_prng_init returned APR_ENOTIMPL", rv != APR_ENOTIMPL);
+ ABTS_ASSERT(tc, "apr_crypto_prng_init returned APR_ENOCIPHER", rv != APR_ENOCIPHER);
+ ABTS_ASSERT(tc, "apr_crypto_prng_init failed", rv == APR_SUCCESS);
+
for (i = 0; i < 10; ++i) {
/* Initial seed full of zeros (deterministic) */
memset(seed, 0, sizeof(seed));
- rv = apr_crypto_prng_create(&cprng, 0, 0, seed, pool);
+ rv = apr_crypto_prng_create(&cprng, NULL, cipher, 0, 0, seed, pool);
+ ABTS_ASSERT(tc, "apr_crypto_prng_create returned APR_EINIT", rv != APR_EINIT);
+ ABTS_ASSERT(tc, "apr_crypto_prng_create returned APR_EINVAL", rv != APR_EINVAL);
+ ABTS_ASSERT(tc, "apr_crypto_prng_create returned APR_ENOTIMPL", rv != APR_ENOTIMPL);
+ ABTS_ASSERT(tc, "apr_crypto_prng_create returned APR_ENOCIPHER", rv != APR_ENOCIPHER);
+ ABTS_ASSERT(tc, "apr_crypto_prng_create returned APR_EDSOOPEN", rv != APR_EDSOOPEN);
ABTS_ASSERT(tc, "apr_crypto_prng_create failed", rv == APR_SUCCESS);
+ if (!cprng) {
+ break;
+ }
/* Second time and more, change one bit of the seed */
if (i != 0) {
@@ -2488,6 +2507,16 @@ static void test_crypto_prng(abts_case *
apr_pool_destroy(pool);
}
+static void test_crypto_prng_aes256(abts_case *tc, void *data)
+{
+ return test_crypto_prng(tc, APR_CRYPTO_CIPHER_AES_256_CTR, test_PRNG_kat0_aes256);
+}
+
+static void test_crypto_prng_chacha20(abts_case *tc, void *data)
+{
+ return test_crypto_prng(tc, APR_CRYPTO_CIPHER_CHACHA20_CTR, test_PRNG_kat0_chacha20);
+}
+
#if APR_HAS_FORK
static void test_crypto_fork_random(abts_case *tc, void *data)
{
@@ -2498,11 +2527,20 @@ static void test_crypto_fork_random(abts
apr_size_t nbytes;
apr_proc_t proc;
apr_status_t rv;
+ int flags = 0;
rv = apr_pool_create(&pool, NULL);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
ABTS_PTR_NOTNULL(tc, pool);
+#if APR_HAS_THREADS
+ flags = APR_CRYPTO_PRNG_PER_THREAD;
+#endif
+ rv = apr_crypto_prng_init(pool, NULL, APR_CRYPTO_CIPHER_AUTO, 0, NULL, flags);
+ ABTS_ASSERT(tc, "apr_crypto_prng_init returned APR_EREINIT", rv != APR_EREINIT);
+ ABTS_ASSERT(tc, "apr_crypto_prng_init returned APR_ENOTIMPL", rv != APR_ENOTIMPL);
+ ABTS_ASSERT(tc, "apr_crypto_prng_init failed", rv == APR_SUCCESS);
+
rv = apr_file_pipe_create(&pread, &pwrite, p);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
ABTS_PTR_NOTNULL(tc, pread);
@@ -2537,6 +2575,8 @@ static void test_crypto_fork_random(abts
apr_proc_wait(&proc, &exitcode, &why, APR_WAIT);
if (why != APR_PROC_EXIT) {
+ ABTS_ASSERT(tc, "apr_proc_wait returned APR_PROC_SIGNAL", why != APR_PROC_SIGNAL);
+ ABTS_ASSERT(tc, "apr_proc_wait returned APR_PROC_SIGNAL_CORE", why != (APR_PROC_SIGNAL | APR_PROC_SIGNAL_CORE));
ABTS_FAIL(tc, "child terminated abnormally");
}
else if (exitcode != 0) {
@@ -2579,11 +2619,20 @@ static void test_crypto_thread_random(ab
apr_pool_t *pool = NULL;
apr_status_t rv, ret;
int i, j;
+ int flags = 0;
rv = apr_pool_create(&pool, NULL);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
ABTS_PTR_NOTNULL(tc, pool);
+#if APR_HAS_THREADS
+ flags = APR_CRYPTO_PRNG_PER_THREAD;
+#endif
+ rv = apr_crypto_prng_init(pool, NULL, APR_CRYPTO_CIPHER_AUTO, 0, NULL, flags);
+ ABTS_ASSERT(tc, "apr_crypto_prng_init returned APR_EREINIT", rv != APR_EREINIT);
+ ABTS_ASSERT(tc, "apr_crypto_prng_init returned APR_ENOTIMPL", rv != APR_ENOTIMPL);
+ ABTS_ASSERT(tc, "apr_crypto_prng_init failed", rv == APR_SUCCESS);
+
for (i = 0; i < NUM_THREADS; ++i) {
randbytes[i] = apr_pcalloc(pool, 800);
rv = apr_thread_create(&threads[i], NULL, thread_func,
@@ -2716,7 +2765,8 @@ abts_suite *testcrypto(abts_suite *suite
abts_run_test(suite, test_crypto_equals, NULL);
#if APU_HAVE_CRYPTO_PRNG
- abts_run_test(suite, test_crypto_prng, NULL);
+ abts_run_test(suite, test_crypto_prng_aes256, NULL);
+ abts_run_test(suite, test_crypto_prng_chacha20, NULL);
#if APR_HAS_FORK
abts_run_test(suite, test_crypto_fork_random, NULL);
#endif