1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef CODE_SIGN_RANDOM_HELPER_H
17 #define CODE_SIGN_RANDOM_HELPER_H
18 
19 #include <cstdlib>
20 #include <fcntl.h>
21 #include <mutex>
22 #include <unistd.h>
23 #include "errcode.h"
24 
25 namespace OHOS {
26 namespace Security {
27 namespace CodeSign {
28 
29 static constexpr uint32_t XORSHITF32_FIRST_STEP_LEFT = 13;
30 static constexpr uint32_t XORSHITF32_SECOND_STEP_RIGHT = 17;
31 static constexpr uint32_t XORSHITF32_THIRD_STEP_LEFT = 5;
32 
33 class RandomHelper {
34 public:
GetUint32(uint32_t & randomNum)35     int32_t GetUint32(uint32_t &randomNum)
36     {
37         if (curStat_ == 0) {
38             if (!Init()) {
39                 return CS_ERR_FILE_READ;
40             }
41         }
42         randomNum = XorShift32();
43         return CS_SUCCESS;
44     }
45 
46 private:
Init()47     bool Init()
48     {
49         int fd = open("/dev/urandom", O_RDONLY);
50         if (fd < 0) {
51             LOG_ERROR("open /dev/urandom failed. errno = <%{public}d, %{public}s>",
52                 errno, strerror(errno));
53             return false;
54         }
55         uint32_t ret = 0;
56         ssize_t len = read(fd, &ret, sizeof(ret));
57         (void) close(fd);
58         if (len != sizeof(ret)) {
59             return false;
60         }
61         curStat_ = ret;
62         return true;
63     }
XorShift32()64     uint32_t XorShift32()
65     {
66         uint32_t nextStat = curStat_;
67         nextStat ^= nextStat << XORSHITF32_FIRST_STEP_LEFT;
68         nextStat ^= nextStat >> XORSHITF32_SECOND_STEP_RIGHT;
69         nextStat ^= nextStat << XORSHITF32_THIRD_STEP_LEFT;
70         curStat_ = nextStat;
71         return curStat_;
72     }
73     std::atomic<uint32_t> curStat_ = 0;
74 };
75 }
76 }
77 }
78 #endif