diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2015-04-20 22:46:41 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-04-21 21:30:17 -0400 |
commit | 8fded5925d0a733c46f8d0b5edd1c9b315882b1d (patch) | |
tree | a68eb1c51ed01734d7c09a8cb14327d355c9a4a2 | |
parent | 881cd6c570af412c2fab278b0656f7597dc5ee74 (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>
-rw-r--r-- | crypto/drbg.c | 123 | ||||
-rw-r--r-- | include/crypto/drbg.h | 50 |
2 files changed, 66 insertions, 107 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 | */ |
1476 | static inline void drbg_set_testdata(struct drbg_state *drbg, | 1477 | static 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 | */ |
1656 | static int drbg_kcapi_random(struct crypto_rng *tfm, u8 *rdata, | 1654 | static 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 | */ |
1681 | static int drbg_kcapi_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen) | 1674 | static 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 | ||
1796 | static struct crypto_alg drbg_algs[22]; | 1783 | static 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 | */ |
1803 | static inline void __init drbg_fill_array(struct crypto_alg *alg, | 1790 | static 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 | ||
1842 | static int __init drbg_init(void) | 1827 | static 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 | ||
1875 | static void __exit drbg_exit(void) | 1860 | static 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 | ||
1880 | module_init(drbg_init); | 1865 | module_init(drbg_init); |
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h index a43a7ed4d9fc..480d7a0f4dac 100644 --- a/include/crypto/drbg.h +++ b/include/crypto/drbg.h | |||
@@ -121,7 +121,7 @@ struct drbg_state { | |||
121 | #endif | 121 | #endif |
122 | const struct drbg_state_ops *d_ops; | 122 | const struct drbg_state_ops *d_ops; |
123 | const struct drbg_core *core; | 123 | const struct drbg_core *core; |
124 | struct drbg_test_data *test_data; | 124 | struct drbg_string test_data; |
125 | }; | 125 | }; |
126 | 126 | ||
127 | static inline __u8 drbg_statelen(struct drbg_state *drbg) | 127 | static inline __u8 drbg_statelen(struct drbg_state *drbg) |
@@ -177,19 +177,8 @@ static inline size_t drbg_max_requests(struct drbg_state *drbg) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | /* | 179 | /* |
180 | * kernel crypto API input data structure for DRBG generate in case dlen | ||
181 | * is set to 0 | ||
182 | */ | ||
183 | struct drbg_gen { | ||
184 | unsigned char *outbuf; /* output buffer for random numbers */ | ||
185 | unsigned int outlen; /* size of output buffer */ | ||
186 | struct drbg_string *addtl; /* additional information string */ | ||
187 | struct drbg_test_data *test_data; /* test data */ | ||
188 | }; | ||
189 | |||
190 | /* | ||
191 | * This is a wrapper to the kernel crypto API function of | 180 | * This is a wrapper to the kernel crypto API function of |
192 | * crypto_rng_get_bytes() to allow the caller to provide additional data. | 181 | * crypto_rng_generate() to allow the caller to provide additional data. |
193 | * | 182 | * |
194 | * @drng DRBG handle -- see crypto_rng_get_bytes | 183 | * @drng DRBG handle -- see crypto_rng_get_bytes |
195 | * @outbuf output buffer -- see crypto_rng_get_bytes | 184 | * @outbuf output buffer -- see crypto_rng_get_bytes |
@@ -204,21 +193,15 @@ static inline int crypto_drbg_get_bytes_addtl(struct crypto_rng *drng, | |||
204 | unsigned char *outbuf, unsigned int outlen, | 193 | unsigned char *outbuf, unsigned int outlen, |
205 | struct drbg_string *addtl) | 194 | struct drbg_string *addtl) |
206 | { | 195 | { |
207 | int ret; | 196 | return crypto_rng_generate(drng, addtl->buf, addtl->len, |
208 | struct drbg_gen genbuf; | 197 | outbuf, outlen); |
209 | genbuf.outbuf = outbuf; | ||
210 | genbuf.outlen = outlen; | ||
211 | genbuf.addtl = addtl; | ||
212 | genbuf.test_data = NULL; | ||
213 | ret = crypto_rng_get_bytes(drng, (u8 *)&genbuf, 0); | ||
214 | return ret; | ||
215 | } | 198 | } |
216 | 199 | ||
217 | /* | 200 | /* |
218 | * TEST code | 201 | * TEST code |
219 | * | 202 | * |
220 | * This is a wrapper to the kernel crypto API function of | 203 | * This is a wrapper to the kernel crypto API function of |
221 | * crypto_rng_get_bytes() to allow the caller to provide additional data and | 204 | * crypto_rng_generate() to allow the caller to provide additional data and |
222 | * allow furnishing of test_data | 205 | * allow furnishing of test_data |
223 | * | 206 | * |
224 | * @drng DRBG handle -- see crypto_rng_get_bytes | 207 | * @drng DRBG handle -- see crypto_rng_get_bytes |
@@ -236,14 +219,10 @@ static inline int crypto_drbg_get_bytes_addtl_test(struct crypto_rng *drng, | |||
236 | struct drbg_string *addtl, | 219 | struct drbg_string *addtl, |
237 | struct drbg_test_data *test_data) | 220 | struct drbg_test_data *test_data) |
238 | { | 221 | { |
239 | int ret; | 222 | crypto_rng_set_entropy(drng, test_data->testentropy->buf, |
240 | struct drbg_gen genbuf; | 223 | test_data->testentropy->len); |
241 | genbuf.outbuf = outbuf; | 224 | return crypto_rng_generate(drng, addtl->buf, addtl->len, |
242 | genbuf.outlen = outlen; | 225 | outbuf, outlen); |
243 | genbuf.addtl = addtl; | ||
244 | genbuf.test_data = test_data; | ||
245 | ret = crypto_rng_get_bytes(drng, (u8 *)&genbuf, 0); | ||
246 | return ret; | ||
247 | } | 226 | } |
248 | 227 | ||
249 | /* | 228 | /* |
@@ -264,14 +243,9 @@ static inline int crypto_drbg_reset_test(struct crypto_rng *drng, | |||
264 | struct drbg_string *pers, | 243 | struct drbg_string *pers, |
265 | struct drbg_test_data *test_data) | 244 | struct drbg_test_data *test_data) |
266 | { | 245 | { |
267 | int ret; | 246 | crypto_rng_set_entropy(drng, test_data->testentropy->buf, |
268 | struct drbg_gen genbuf; | 247 | test_data->testentropy->len); |
269 | genbuf.outbuf = NULL; | 248 | return crypto_rng_reset(drng, pers->buf, pers->len); |
270 | genbuf.outlen = 0; | ||
271 | genbuf.addtl = pers; | ||
272 | genbuf.test_data = test_data; | ||
273 | ret = crypto_rng_reset(drng, (u8 *)&genbuf, 0); | ||
274 | return ret; | ||
275 | } | 249 | } |
276 | 250 | ||
277 | /* DRBG type flags */ | 251 | /* DRBG type flags */ |