[PATCH v7 7/7] User interface to DRBG
Stephan Mueller
smueller at chronox.de
Wed Mar 19 08:40:03 CET 2014
DRBG Usage
==========
The SP 800-90A DRBG allows the user to specify a personalization string
for initialization as well as an additional information string for each
random number request. The following code fragments show how a caller
uses the kernel crypto API to use the full functionality of the DRBG.
Usage without any additional data
---------------------------------
gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM);
Usage with personalization string during initialization
-------------------------------------------------------
struct drbg_string pers;
drbg_string_fill(&pers, "string", strlen("string"));
// The reset completely re-initializes the DRBG with the provided
// personalization string without changing the DRBG type
ret = gcry_control(GCRYCTL_DRBG_REINIT, 0, &pers, NULL);
gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM);
Usage with additional information string during random number request
---------------------------------------------------------------------
struct drbg_string addtl;
drbg_string_fill(&addtl, "string", strlen("string"));
// The following call is a wrapper to gcry_randomize() and returns
// the same error codes.
gcry_randomize_drbg(outbuf, OUTLEN, GCRY_STRONG_RANDOM, &addtl);
Usage with personalization and additional information strings
-------------------------------------------------------------
Just mix both scenarios above.
Switch the DRBG type to some other type
---------------------------------------
// Switch to CTR DRBG AES-128 without prediction resistance
ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_NOPR_CTRAES128, NULL, NULL);
gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM);
Changes v3:
* export only one gcry_control function
* revamp of flags definition to avoid double information
Signed-off-by: Stephan Mueller <smueller at chronox.de>
---
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
index c84a3f7..f7195bc 100644
--- a/src/gcrypt.h.in
+++ b/src/gcrypt.h.in
@@ -193,7 +193,7 @@ gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
/* Return an error value with the system error ERR. */
gcry_err_code_t gcry_error_from_errno (int err);
-
+
/* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore
used. However we keep it to allow for some source code
compatibility if used in the standard way. */
@@ -228,7 +228,7 @@ struct gcry_thread_cbs
(GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))}
-
+
/* A generic context object as used by some functions. */
struct gcry_context;
typedef struct gcry_context *gcry_ctx_t;
@@ -254,7 +254,7 @@ typedef struct
} gcry_buffer_t;
-
+
/* Check that the library fulfills the version requirement. */
const char *gcry_check_version (const char *req_version);
@@ -329,13 +329,14 @@ enum gcry_ctl_cmds
GCRYCTL_SET_CCM_LENGTHS = 69,
GCRYCTL_CLOSE_RANDOM_DEVICE = 70,
GCRYCTL_INACTIVATE_FIPS_FLAG = 71,
- GCRYCTL_REACTIVATE_FIPS_FLAG = 72
+ GCRYCTL_REACTIVATE_FIPS_FLAG = 72,
+ GCRYCTL_DRBG_REINIT = 73,
};
/* Perform various operations defined by CMD. */
gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...);
-
+
/* S-expression management. */
/* The object to represent an S-expression as used with the public key
@@ -477,7 +478,7 @@ gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp,
const char *list,
...) _GCRY_GCC_ATTR_SENTINEL(0);
-
+
/*******************************************
* *
* Multi Precision Integer Functions *
@@ -833,7 +834,7 @@ gcry_mpi_t _gcry_mpi_get_const (int no);
#endif /* GCRYPT_NO_MPI_MACROS */
-
+
/************************************
* *
* Symmetric Cipher Functions *
@@ -1015,7 +1016,7 @@ size_t gcry_cipher_get_algo_blklen (int algo);
#define gcry_cipher_test_algo(a) \
gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
-
+
/************************************
* *
* Asymmetric Cipher Functions *
@@ -1114,7 +1115,7 @@ gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
gcry_error_t gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp,
int mode, gcry_ctx_t ctx);
-
+
/************************************
* *
@@ -1291,7 +1292,7 @@ void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
#define gcry_md_get_asnoid(a,b,n) \
gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
-
+
/**********************************************
* *
@@ -1411,7 +1412,7 @@ int gcry_mac_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
#define gcry_mac_test_algo(a) \
gcry_mac_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
-
+
/******************************
* *
* Key Derivation Functions *
@@ -1439,7 +1440,7 @@ gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
-
+
/************************************
* *
* Random Generating Functions *
@@ -1508,7 +1509,7 @@ void gcry_create_nonce (void *buffer, size_t length);
-
+
/*******************************/
/* */
/* Prime Number Functions */
@@ -1567,7 +1568,7 @@ void gcry_prime_release_factors (gcry_mpi_t *factors);
gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags);
-
+
/************************************
* *
* Miscellaneous Stuff *
@@ -1672,6 +1673,134 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
/* Return true if Libgcrypt is in FIPS mode. */
#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
+/* DRBG test data */
+struct drbg_test_data {
+ struct drbg_string *testentropy; /* TEST PARAMETER: test entropy */
+};
+
+/* DRBG input data structure for DRBG generate with additional information
+ * string */
+struct drbg_gen {
+ unsigned char *outbuf; /* output buffer for random numbers */
+ unsigned int outlen; /* size of output buffer */
+ struct drbg_string *addtl; /* input buffer for
+ * additional information string */
+ struct drbg_test_data *test_data; /* test data */
+};
+
+/*
+ * Concatenation Helper and string operation helper
+ *
+ * SP800-90A requires the concatenation of different data. To avoid copying
+ * buffers around or allocate additional memory, the following data structure
+ * is used to point to the original memory with its size. In addition, it
+ * is used to build a linked list. The linked list defines the concatenation
+ * of individual buffers. The order of memory block referenced in that
+ * linked list determines the order of concatenation.
+ */
+/* DRBG string definition */
+struct drbg_string {
+ const unsigned char *buf;
+ size_t len;
+ struct drbg_string *next;
+};
+
+static inline void drbg_string_fill(struct drbg_string *string,
+ const unsigned char *buf, size_t len)
+{
+ string->buf = buf;
+ string->len = len;
+ string->next = NULL;
+}
+
+/* this is a wrapper function for users of libgcrypt */
+static inline void gcry_randomize_drbg(void *outbuf, size_t outlen,
+ enum gcry_random_level level,
+ struct drbg_string *addtl)
+{
+ struct drbg_gen genbuf;
+ genbuf.outbuf = outbuf;
+ genbuf.outlen = outlen;
+ genbuf.addtl = addtl;
+ genbuf.test_data = NULL;
+ gcry_randomize(&genbuf, 0, level);
+}
+
+/* this is a wrapper function for users of libgcrypt */
+static inline void gcry_randomize_drbg_test(void *outbuf, size_t outlen,
+ enum gcry_random_level level,
+ struct drbg_string *addtl,
+ struct drbg_test_data *test_data)
+{
+ struct drbg_gen genbuf;
+ genbuf.outbuf = outbuf;
+ genbuf.outlen = outlen;
+ genbuf.addtl = addtl;
+ genbuf.test_data = test_data;
+ gcry_randomize(&genbuf, 0, level);
+}
+
+
+/*
+ * DRBG flags bitmasks
+ *
+ * 31 (B) 28 19 (A) 0
+ * +-+-+-+--------+---+-----------+-----+
+ * |~|~|u|~~~~~~~~| 3 | 2 | 1 |
+ * +-+-+-+--------+- -+-----------+-----+
+ * ctl flg| |drbg use selection flags
+ *
+ */
+
+/* internal state control flags (B) */
+#define DRBG_PREDICTION_RESIST ((u_int32_t)1<<28)
+
+/* CTR type modifiers (A.1)*/
+#define DRBG_CTRAES ((u_int32_t)1<<0)
+#define DRBG_CTRSERPENT ((u_int32_t)1<<1)
+#define DRBG_CTRTWOFISH ((u_int32_t)1<<2)
+#define DRBG_CTR_MASK (DRBG_CTRAES | DRBG_CTRSERPENT | DRBG_CTRTWOFISH)
+
+/* HASH type modifiers (A.2)*/
+#define DRBG_HASHSHA1 ((u_int32_t)1<<4)
+#define DRBG_HASHSHA224 ((u_int32_t)1<<5)
+#define DRBG_HASHSHA256 ((u_int32_t)1<<6)
+#define DRBG_HASHSHA384 ((u_int32_t)1<<7)
+#define DRBG_HASHSHA512 ((u_int32_t)1<<8)
+#define DRBG_HASH_MASK (DRBG_HASHSHA1 | DRBG_HASHSHA224 | \
+ DRBG_HASHSHA256 | DRBG_HASHSHA384 | \
+ DRBG_HASHSHA512)
+/* type modifiers (A.3)*/
+#define DRBG_HMAC ((u_int32_t)1<<12)
+#define DRBG_SYM128 ((u_int32_t)1<<13)
+#define DRBG_SYM192 ((u_int32_t)1<<14)
+#define DRBG_SYM256 ((u_int32_t)1<<15)
+#define DRBG_TYPE_MASK (DRBG_HMAC | DRBG_SYM128 | DRBG_SYM192 | \
+ DRBG_SYM256)
+#define DRBG_CIPHER_MASK (DRBG_CTR_MASK | DRBG_HASH_MASK | DRBG_TYPE_MASK)
+
+#define DRBG_PR_CTRAES128 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM128)
+#define DRBG_PR_CTRAES192 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM192)
+#define DRBG_PR_CTRAES256 (DRBG_PREDICTION_RESIST | DRBG_CTRAES | DRBG_SYM256)
+#define DRBG_NOPR_CTRAES128 (DRBG_CTRAES | DRBG_SYM128)
+#define DRBG_NOPR_CTRAES192 (DRBG_CTRAES | DRBG_SYM192)
+#define DRBG_NOPR_CTRAES256 (DRBG_CTRAES | DRBG_SYM256)
+#define DRBG_PR_HASHSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1)
+#define DRBG_PR_HASHSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256)
+#define DRBG_PR_HASHSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384)
+#define DRBG_PR_HASHSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512)
+#define DRBG_NOPR_HASHSHA1 (DRBG_HASHSHA1)
+#define DRBG_NOPR_HASHSHA256 (DRBG_HASHSHA256)
+#define DRBG_NOPR_HASHSHA384 (DRBG_HASHSHA384)
+#define DRBG_NOPR_HASHSHA512 (DRBG_HASHSHA512)
+#define DRBG_PR_HMACSHA1 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA1 | DRBG_HMAC)
+#define DRBG_PR_HMACSHA256 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA256|DRBG_HMAC)
+#define DRBG_PR_HMACSHA384 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA384|DRBG_HMAC)
+#define DRBG_PR_HMACSHA512 (DRBG_PREDICTION_RESIST | DRBG_HASHSHA512|DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA1 (DRBG_HASHSHA1 | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA256 (DRBG_HASHSHA256 | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA384 (DRBG_HASHSHA384 | DRBG_HMAC)
+#define DRBG_NOPR_HMACSHA512 (DRBG_HASHSHA512 | DRBG_HMAC)
#if 0 /* (Keep Emacsens' auto-indent happy.) */
{
More information about the Gcrypt-devel
mailing list