1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2019-04-25     tyx          the first version
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <hw_rng.h>
14 
15 /* Used to save default RNG Context */
16 static struct rt_hwcrypto_ctx *ctx_default;
17 
18 /**
19  * @brief           Creating RNG Context
20  *
21  * @param device    Hardware crypto device
22  *
23  * @return          RNG context
24  */
rt_hwcrypto_rng_create(struct rt_hwcrypto_device * device)25 struct rt_hwcrypto_ctx *rt_hwcrypto_rng_create(struct rt_hwcrypto_device *device)
26 {
27     struct rt_hwcrypto_ctx *ctx;
28 
29     ctx = rt_hwcrypto_ctx_create(device, HWCRYPTO_TYPE_RNG, sizeof(struct hwcrypto_rng));
30     return ctx;
31 }
32 
33 /**
34  * @brief           Destroy RNG Context
35  *
36  * @param ctx       RNG context
37  */
rt_hwcrypto_rng_destroy(struct rt_hwcrypto_ctx * ctx)38 void rt_hwcrypto_rng_destroy(struct rt_hwcrypto_ctx *ctx)
39 {
40     /* Destroy the defaule RNG Context ? */
41     if (ctx == ctx_default)
42     {
43         ctx_default = RT_NULL;
44     }
45     rt_hwcrypto_ctx_destroy(ctx);
46 }
47 
48 /**
49  * @brief           Setting RNG default devices
50  *
51  * @return          RT_EOK on success.
52  */
rt_hwcrypto_rng_default(struct rt_hwcrypto_device * device)53 rt_err_t rt_hwcrypto_rng_default(struct rt_hwcrypto_device *device)
54 {
55     struct rt_hwcrypto_ctx *tmp_ctx;
56 
57     /* if device is null, destroy default RNG Context */
58     if (device == RT_NULL)
59     {
60         if (ctx_default)
61         {
62             rt_hwcrypto_rng_destroy(ctx_default);
63             ctx_default = RT_NULL;
64         }
65         return RT_EOK;
66     }
67     /* Try create RNG Context */
68     tmp_ctx = rt_hwcrypto_rng_create(device);
69     if (tmp_ctx == RT_NULL)
70     {
71         return -RT_ERROR;
72     }
73     /* create RNG Context success, update default RNG Context */
74     rt_hwcrypto_rng_destroy(ctx_default);
75     ctx_default = tmp_ctx;
76 
77     return RT_EOK;
78 }
79 
80 /**
81  * @brief           Getting Random Numbers from RNG Context
82  *
83  * @param ctx       RNG context
84  *
85  * @return          Random number
86  */
rt_hwcrypto_rng_update_ctx(struct rt_hwcrypto_ctx * ctx)87 rt_uint32_t rt_hwcrypto_rng_update_ctx(struct rt_hwcrypto_ctx *ctx)
88 {
89     if (ctx)
90     {
91         return ((struct hwcrypto_rng *)ctx)->ops->update((struct hwcrypto_rng *)ctx);
92     }
93     return 0;
94 }
95 
96 /**
97  * @brief           Return a random number
98  *
99  * @return          Random number
100  */
rt_hwcrypto_rng_update(void)101 rt_uint32_t rt_hwcrypto_rng_update(void)
102 {
103     /* Default device does not exist ? */
104     if (ctx_default == RT_NULL)
105     {
106         /* try create Context from default device */
107         rt_hwcrypto_rng_default(rt_hwcrypto_dev_default());
108     }
109     return rt_hwcrypto_rng_update_ctx(ctx_default);
110 }
111