]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
b0edda11 | 2 | * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. |
0c61e299 | 3 | * |
b1322259 RS |
4 | * Licensed under the OpenSSL license (the "License"). You may not use |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
0c61e299 RL |
8 | */ |
9 | ||
da8fc25a | 10 | #include "e_os.h" |
0c61e299 | 11 | |
bc36ee62 | 12 | #if defined(OPENSSL_SYS_VMS) |
fc1d73bb | 13 | # include "internal/cryptlib.h" |
da8fc25a | 14 | # include <openssl/rand.h> |
93bf1945 | 15 | # include "internal/rand_int.h" |
da8fc25a | 16 | # include "rand_lcl.h" |
0f113f3e MC |
17 | # include <descrip.h> |
18 | # include <jpidef.h> | |
19 | # include <ssdef.h> | |
20 | # include <starlet.h> | |
5fc2c689 | 21 | # include <efndef> |
0f113f3e MC |
22 | # ifdef __DECC |
23 | # pragma message disable DOLLARID | |
24 | # endif | |
0c61e299 | 25 | |
8389ec4b RS |
26 | # ifndef OPENSSL_RAND_SEED_OS |
27 | # error "Unsupported seeding method configured; must be os" | |
28 | # endif | |
29 | ||
0f113f3e MC |
30 | /* |
31 | * Use 32-bit pointers almost everywhere. Define the type to which to cast a | |
32 | * pointer passed to an external function. | |
537c9823 | 33 | */ |
0f113f3e MC |
34 | # if __INITIAL_POINTER_SIZE == 64 |
35 | # define PTR_T __void_ptr64 | |
36 | # pragma pointer_size save | |
37 | # pragma pointer_size 32 | |
da8fc25a | 38 | # else |
0f113f3e | 39 | # define PTR_T void * |
da8fc25a | 40 | # endif |
0f113f3e MC |
41 | |
42 | static struct items_data_st { | |
5fc2c689 | 43 | short length, code; /* length is number of bytes */ |
0f113f3e | 44 | } items_data[] = { |
5fc2c689 RL |
45 | {4, JPI$_BUFIO}, |
46 | {4, JPI$_CPUTIM}, | |
47 | {4, JPI$_DIRIO}, | |
48 | {4, JPI$_IMAGECOUNT}, | |
49 | {8, JPI$_LAST_LOGIN_I}, | |
50 | {8, JPI$_LOGINTIM}, | |
51 | {4, JPI$_PAGEFLTS}, | |
52 | {4, JPI$_PID}, | |
53 | {4, JPI$_PPGCNT}, | |
54 | {4, JPI$_WSPEAK}, | |
55 | {4, JPI$_FINALEXC}, | |
da8fc25a | 56 | {0, 0} |
0f113f3e | 57 | }; |
537c9823 | 58 | |
fc1d73bb RL |
59 | /* |
60 | * We assume there we get about 4 bits of entropy per byte from the items | |
61 | * above, with a bit of scrambling added rand_pool_acquire_entropy() | |
62 | */ | |
63 | #define ENTROPY_BITS_PER_BYTE 4 | |
64 | ||
6decf943 | 65 | size_t rand_pool_acquire_entropy(RAND_POOL *pool) |
0f113f3e | 66 | { |
5fc2c689 | 67 | /* determine the number of items in the JPI array */ |
5fc2c689 | 68 | struct items_data_st item_entry; |
fc1d73bb RL |
69 | size_t item_entry_count = OSSL_NELEM(items_data); |
70 | /* Create the 32-bit JPI itemlist array to hold item_data content */ | |
0f113f3e | 71 | struct { |
fc1d73bb RL |
72 | uint16_t length, code; |
73 | uint32_t *buffer; | |
74 | uint32_t *retlen; | |
da8fc25a | 75 | } item[item_entry_count], *pitem; |
0f113f3e | 76 | struct items_data_st *pitems_data; |
fc1d73bb RL |
77 | /* 8 bytes (two longs) per entry max */ |
78 | uint32_t data_buffer[(item_entry_count * 2) + 4]; | |
79 | uint32_t iosb[2]; | |
80 | uint32_t sys_time[2]; | |
81 | uint32_t *ptr; | |
82 | size_t i, j ; | |
83 | size_t tmp_length = 0; | |
84 | size_t total_length = 0; | |
85 | size_t bytes_needed = rand_pool_bytes_needed(pool, ENTROPY_BITS_PER_BYTE); | |
86 | size_t bytes_remaining = rand_pool_bytes_remaining(pool); | |
73986238 | 87 | |
5fc2c689 | 88 | /* Setup itemlist for GETJPI */ |
da8fc25a RS |
89 | pitems_data = items_data; |
90 | for (pitem = item; pitems_data->length != 0; pitem++) { | |
0f113f3e | 91 | pitem->length = pitems_data->length; |
5fc2c689 RL |
92 | pitem->code = pitems_data->code; |
93 | pitem->buffer = &data_buffer[total_length]; | |
0f113f3e | 94 | pitem->retlen = 0; |
5fc2c689 | 95 | /* total_length is in longwords */ |
da8fc25a | 96 | total_length += pitems_data->length / 4; |
0f113f3e | 97 | pitems_data++; |
0f113f3e MC |
98 | } |
99 | pitem->length = pitem->code = 0; | |
73986238 | 100 | |
5fc2c689 | 101 | /* Fill data_buffer with various info bits from this process */ |
da8fc25a RS |
102 | if (sys$getjpiw(EFN$C_ENF, NULL, NULL, item, &iosb, 0, 0) != SS$_NORMAL) |
103 | return 0; | |
5fc2c689 | 104 | |
da8fc25a RS |
105 | /* Now twist that data to seed the SSL random number init */ |
106 | for (i = 0; i < total_length; i++) { | |
107 | sys$gettim((struct _generic_64 *)&sys_time[0]); | |
108 | srand(sys_time[0] * data_buffer[0] * data_buffer[1] + i); | |
5fc2c689 | 109 | |
da8fc25a RS |
110 | if (i == (total_length - 1)) { /* for JPI$_FINALEXC */ |
111 | ptr = &data_buffer[i]; | |
112 | for (j = 0; j < 4; j++) { | |
113 | data_buffer[i + j] = ptr[j]; | |
5fc2c689 | 114 | /* OK to use rand() just to scramble the seed */ |
da8fc25a RS |
115 | data_buffer[i + j] ^= (sys_time[0] ^ rand()); |
116 | tmp_length++; | |
5fc2c689 | 117 | } |
da8fc25a RS |
118 | } else { |
119 | /* OK to use rand() just to scramble the seed */ | |
120 | data_buffer[i] ^= (sys_time[0] ^ rand()); | |
0f113f3e MC |
121 | } |
122 | } | |
5fc2c689 | 123 | |
da8fc25a RS |
124 | total_length += (tmp_length - 1); |
125 | ||
fc1d73bb RL |
126 | /* Change the total length to number of bytes */ |
127 | total_length *= 4; | |
128 | ||
c16de9d8 | 129 | /* |
fc1d73bb | 130 | * If we can't feed the requirements from the caller, we're in deep trouble. |
c16de9d8 | 131 | */ |
fc1d73bb RL |
132 | if (!ossl_assert(total_length >= bytes_needed)) { |
133 | char neededstr[20]; | |
134 | char availablestr[20]; | |
135 | ||
136 | BIO_snprintf(neededstr, sizeof(neededstr), "%zu", bytes_needed); | |
137 | BIO_snprintf(availablestr, sizeof(availablestr), "%zu", total_length); | |
138 | RANDerr(RAND_F_RAND_POOL_ACQUIRE_ENTROPY, | |
139 | RAND_R_RANDOM_POOL_UNDERFLOW); | |
140 | ERR_add_error_data(4, "Needed: ", neededstr, ", Available: ", | |
141 | availablestr); | |
142 | return 0; | |
143 | } | |
144 | ||
145 | /* | |
146 | * Try not to overfeed the pool | |
147 | */ | |
148 | if (total_length > bytes_remaining) | |
149 | total_length = bytes_remaining; | |
150 | ||
8e2bec9b RL |
151 | rand_pool_add(pool, (PTR_T)data_buffer, total_length, |
152 | total_length * ENTROPY_BITS_PER_BYTE); | |
153 | return rand_pool_entropy_available(pool); | |
0c61e299 RL |
154 | } |
155 | ||
156 | #endif |