summaryrefslogtreecommitdiffstats
path: root/crypto/drbg.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2015-04-20 22:46:41 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2015-04-21 21:30:17 -0400
commit8fded5925d0a733c46f8d0b5edd1c9b315882b1d (patch)
treea68eb1c51ed01734d7c09a8cb14327d355c9a4a2 /crypto/drbg.c
parent881cd6c570af412c2fab278b0656f7597dc5ee74 (diff)
crypto: drbg - Convert to new rng interface
This patch converts the DRBG implementation to the new low-level rng interface. This allows us to get rid of struct drbg_gen by using the new RNG API instead. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Acked-by: Stephan Mueller <smueller@chronox.de>
Diffstat (limited to 'crypto/drbg.c')
-rw-r--r--crypto/drbg.c123
1 files changed, 54 insertions, 69 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 5bce15918de5..ec6bffd77001 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -235,7 +235,7 @@ static bool drbg_fips_continuous_test(struct drbg_state *drbg,
235#ifdef CONFIG_CRYPTO_FIPS 235#ifdef CONFIG_CRYPTO_FIPS
236 int ret = 0; 236 int ret = 0;
237 /* skip test if we test the overall system */ 237 /* skip test if we test the overall system */
238 if (drbg->test_data) 238 if (list_empty(&drbg->test_data.list))
239 return true; 239 return true;
240 /* only perform test in FIPS mode */ 240 /* only perform test in FIPS mode */
241 if (0 == fips_enabled) 241 if (0 == fips_enabled)
@@ -1068,9 +1068,9 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
1068 return -EINVAL; 1068 return -EINVAL;
1069 } 1069 }
1070 1070
1071 if (drbg->test_data && drbg->test_data->testentropy) { 1071 if (list_empty(&drbg->test_data.list)) {
1072 drbg_string_fill(&data1, drbg->test_data->testentropy->buf, 1072 drbg_string_fill(&data1, drbg->test_data.buf,
1073 drbg->test_data->testentropy->len); 1073 drbg->test_data.len);
1074 pr_devel("DRBG: using test entropy\n"); 1074 pr_devel("DRBG: using test entropy\n");
1075 } else { 1075 } else {
1076 /* 1076 /*
@@ -1471,15 +1471,16 @@ static int drbg_uninstantiate(struct drbg_state *drbg)
1471 * Helper function for setting the test data in the DRBG 1471 * Helper function for setting the test data in the DRBG
1472 * 1472 *
1473 * @drbg DRBG state handle 1473 * @drbg DRBG state handle
1474 * @test_data test data to sets 1474 * @data test data
1475 * @len test data length
1475 */ 1476 */
1476static inline void drbg_set_testdata(struct drbg_state *drbg, 1477static void drbg_kcapi_set_entropy(struct crypto_rng *tfm,
1477 struct drbg_test_data *test_data) 1478 const u8 *data, unsigned int len)
1478{ 1479{
1479 if (!test_data || !test_data->testentropy) 1480 struct drbg_state *drbg = crypto_rng_ctx(tfm);
1480 return; 1481
1481 mutex_lock(&drbg->drbg_mutex);; 1482 mutex_lock(&drbg->drbg_mutex);
1482 drbg->test_data = test_data; 1483 drbg_string_fill(&drbg->test_data, data, len);
1483 mutex_unlock(&drbg->drbg_mutex); 1484 mutex_unlock(&drbg->drbg_mutex);
1484} 1485}
1485 1486
@@ -1645,63 +1646,49 @@ static void drbg_kcapi_cleanup(struct crypto_tfm *tfm)
1645 * Generate random numbers invoked by the kernel crypto API: 1646 * Generate random numbers invoked by the kernel crypto API:
1646 * The API of the kernel crypto API is extended as follows: 1647 * The API of the kernel crypto API is extended as follows:
1647 * 1648 *
1648 * If dlen is larger than zero, rdata is interpreted as the output buffer 1649 * src is additional input supplied to the RNG.
1649 * where random data is to be stored. 1650 * slen is the length of src.
1650 * 1651 * dst is the output buffer where random data is to be stored.
1651 * If dlen is zero, rdata is interpreted as a pointer to a struct drbg_gen 1652 * dlen is the length of dst.
1652 * which holds the additional information string that is used for the
1653 * DRBG generation process. The output buffer that is to be used to store
1654 * data is also pointed to by struct drbg_gen.
1655 */ 1653 */
1656static int drbg_kcapi_random(struct crypto_rng *tfm, u8 *rdata, 1654static int drbg_kcapi_random(struct crypto_rng *tfm,
1657 unsigned int dlen) 1655 const u8 *src, unsigned int slen,
1656 u8 *dst, unsigned int dlen)
1658{ 1657{
1659 struct drbg_state *drbg = crypto_rng_ctx(tfm); 1658 struct drbg_state *drbg = crypto_rng_ctx(tfm);
1660 if (0 < dlen) { 1659 struct drbg_string *addtl = NULL;
1661 return drbg_generate_long(drbg, rdata, dlen, NULL); 1660 struct drbg_string string;
1662 } else { 1661
1663 struct drbg_gen *data = (struct drbg_gen *)rdata; 1662 if (slen) {
1664 struct drbg_string addtl;
1665 /* catch NULL pointer */
1666 if (!data)
1667 return 0;
1668 drbg_set_testdata(drbg, data->test_data);
1669 /* linked list variable is now local to allow modification */ 1663 /* linked list variable is now local to allow modification */
1670 drbg_string_fill(&addtl, data->addtl->buf, data->addtl->len); 1664 drbg_string_fill(&string, src, slen);
1671 return drbg_generate_long(drbg, data->outbuf, data->outlen, 1665 addtl = &string;
1672 &addtl);
1673 } 1666 }
1667
1668 return drbg_generate_long(drbg, dst, dlen, addtl);
1674} 1669}
1675 1670
1676/* 1671/*
1677 * Seed the DRBG invoked by the kernel crypto API 1672 * Seed the DRBG invoked by the kernel crypto API
1678 * Similar to the generate function of drbg_kcapi_random, this
1679 * function extends the kernel crypto API interface with struct drbg_gen
1680 */ 1673 */
1681static int drbg_kcapi_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen) 1674static int drbg_kcapi_seed(struct crypto_rng *tfm,
1675 const u8 *seed, unsigned int slen)
1682{ 1676{
1683 struct drbg_state *drbg = crypto_rng_ctx(tfm); 1677 struct drbg_state *drbg = crypto_rng_ctx(tfm);
1684 struct crypto_tfm *tfm_base = crypto_rng_tfm(tfm); 1678 struct crypto_tfm *tfm_base = crypto_rng_tfm(tfm);
1685 bool pr = false; 1679 bool pr = false;
1686 struct drbg_string seed_string; 1680 struct drbg_string string;
1681 struct drbg_string *seed_string = NULL;
1687 int coreref = 0; 1682 int coreref = 0;
1688 1683
1689 drbg_convert_tfm_core(crypto_tfm_alg_driver_name(tfm_base), &coreref, 1684 drbg_convert_tfm_core(crypto_tfm_alg_driver_name(tfm_base), &coreref,
1690 &pr); 1685 &pr);
1691 if (0 < slen) { 1686 if (0 < slen) {
1692 drbg_string_fill(&seed_string, seed, slen); 1687 drbg_string_fill(&string, seed, slen);
1693 return drbg_instantiate(drbg, &seed_string, coreref, pr); 1688 seed_string = &string;
1694 } else {
1695 struct drbg_gen *data = (struct drbg_gen *)seed;
1696 /* allow invocation of API call with NULL, 0 */
1697 if (!data)
1698 return drbg_instantiate(drbg, NULL, coreref, pr);
1699 drbg_set_testdata(drbg, data->test_data);
1700 /* linked list variable is now local to allow modification */
1701 drbg_string_fill(&seed_string, data->addtl->buf,
1702 data->addtl->len);
1703 return drbg_instantiate(drbg, &seed_string, coreref, pr);
1704 } 1689 }
1690
1691 return drbg_instantiate(drbg, seed_string, coreref, pr);
1705} 1692}
1706 1693
1707/*************************************************************** 1694/***************************************************************
@@ -1793,32 +1780,31 @@ outbuf:
1793#endif /* CONFIG_CRYPTO_FIPS */ 1780#endif /* CONFIG_CRYPTO_FIPS */
1794} 1781}
1795 1782
1796static struct crypto_alg drbg_algs[22]; 1783static struct rng_alg drbg_algs[22];
1797 1784
1798/* 1785/*
1799 * Fill the array drbg_algs used to register the different DRBGs 1786 * Fill the array drbg_algs used to register the different DRBGs
1800 * with the kernel crypto API. To fill the array, the information 1787 * with the kernel crypto API. To fill the array, the information
1801 * from drbg_cores[] is used. 1788 * from drbg_cores[] is used.
1802 */ 1789 */
1803static inline void __init drbg_fill_array(struct crypto_alg *alg, 1790static inline void __init drbg_fill_array(struct rng_alg *alg,
1804 const struct drbg_core *core, int pr) 1791 const struct drbg_core *core, int pr)
1805{ 1792{
1806 int pos = 0; 1793 int pos = 0;
1807 static int priority = 100; 1794 static int priority = 100;
1808 1795
1809 memset(alg, 0, sizeof(struct crypto_alg)); 1796 memcpy(alg->base.cra_name, "stdrng", 6);
1810 memcpy(alg->cra_name, "stdrng", 6);
1811 if (pr) { 1797 if (pr) {
1812 memcpy(alg->cra_driver_name, "drbg_pr_", 8); 1798 memcpy(alg->base.cra_driver_name, "drbg_pr_", 8);
1813 pos = 8; 1799 pos = 8;
1814 } else { 1800 } else {
1815 memcpy(alg->cra_driver_name, "drbg_nopr_", 10); 1801 memcpy(alg->base.cra_driver_name, "drbg_nopr_", 10);
1816 pos = 10; 1802 pos = 10;
1817 } 1803 }
1818 memcpy(alg->cra_driver_name + pos, core->cra_name, 1804 memcpy(alg->base.cra_driver_name + pos, core->cra_name,
1819 strlen(core->cra_name)); 1805 strlen(core->cra_name));
1820 1806
1821 alg->cra_priority = priority; 1807 alg->base.cra_priority = priority;
1822 priority++; 1808 priority++;
1823 /* 1809 /*
1824 * If FIPS mode enabled, the selected DRBG shall have the 1810 * If FIPS mode enabled, the selected DRBG shall have the
@@ -1826,17 +1812,16 @@ static inline void __init drbg_fill_array(struct crypto_alg *alg,
1826 * it is selected. 1812 * it is selected.
1827 */ 1813 */
1828 if (fips_enabled) 1814 if (fips_enabled)
1829 alg->cra_priority += 200; 1815 alg->base.cra_priority += 200;
1830 1816
1831 alg->cra_flags = CRYPTO_ALG_TYPE_RNG; 1817 alg->base.cra_ctxsize = sizeof(struct drbg_state);
1832 alg->cra_ctxsize = sizeof(struct drbg_state); 1818 alg->base.cra_module = THIS_MODULE;
1833 alg->cra_type = &crypto_rng_type; 1819 alg->base.cra_init = drbg_kcapi_init;
1834 alg->cra_module = THIS_MODULE; 1820 alg->base.cra_exit = drbg_kcapi_cleanup;
1835 alg->cra_init = drbg_kcapi_init; 1821 alg->generate = drbg_kcapi_random;
1836 alg->cra_exit = drbg_kcapi_cleanup; 1822 alg->seed = drbg_kcapi_seed;
1837 alg->cra_u.rng.rng_make_random = drbg_kcapi_random; 1823 alg->set_ent = drbg_kcapi_set_entropy;
1838 alg->cra_u.rng.rng_reset = drbg_kcapi_reset; 1824 alg->seedsize = 0;
1839 alg->cra_u.rng.seedsize = 0;
1840} 1825}
1841 1826
1842static int __init drbg_init(void) 1827static int __init drbg_init(void)
@@ -1869,12 +1854,12 @@ static int __init drbg_init(void)
1869 drbg_fill_array(&drbg_algs[i], &drbg_cores[j], 1); 1854 drbg_fill_array(&drbg_algs[i], &drbg_cores[j], 1);
1870 for (j = 0; ARRAY_SIZE(drbg_cores) > j; j++, i++) 1855 for (j = 0; ARRAY_SIZE(drbg_cores) > j; j++, i++)
1871 drbg_fill_array(&drbg_algs[i], &drbg_cores[j], 0); 1856 drbg_fill_array(&drbg_algs[i], &drbg_cores[j], 0);
1872 return crypto_register_algs(drbg_algs, (ARRAY_SIZE(drbg_cores) * 2)); 1857 return crypto_register_rngs(drbg_algs, (ARRAY_SIZE(drbg_cores) * 2));
1873} 1858}
1874 1859
1875static void __exit drbg_exit(void) 1860static void __exit drbg_exit(void)
1876{ 1861{
1877 crypto_unregister_algs(drbg_algs, (ARRAY_SIZE(drbg_cores) * 2)); 1862 crypto_unregister_rngs(drbg_algs, (ARRAY_SIZE(drbg_cores) * 2));
1878} 1863}
1879 1864
1880module_init(drbg_init); 1865module_init(drbg_init);