FreeBSD: add file descriptor tracking for _umtx_op
[valgrind.git] / none / tests / s390x / ppno.c
blob6bf4cab551b790f695753a400e2da154735a115d
1 #include "stdio.h"
2 #include "stdbool.h"
3 #include "stdint.h"
4 #include "string.h"
5 #include "vector.h"
7 #define S390_PPNO_SHA512_BLOCK_SIZE (240 / 8)
8 static uint64_t block[S390_PPNO_SHA512_BLOCK_SIZE];
9 #define HASH_COUNT 2 /* exactly two hashes for generate */
10 static uint64_t hash[HASH_COUNT];
12 static void print_sha512_block()
14 printf("Current block state:\n");
15 for(size_t elem = 0; elem < S390_PPNO_SHA512_BLOCK_SIZE; elem++)
17 print_uint64_t(block[elem]);
20 printf("end of block.\n");
23 static void print_sha512_hash()
25 printf("Current hash:\n");
26 for(size_t index = 0; index < HASH_COUNT; index++)
27 print_uint64_t(hash[index]);
29 printf("end of hash\n");
32 /* The problem with this test is different results on different architectures.
33 E.g. z13 will return (1 << 0)|(1 << 3) value while more recent versions of CPU
34 can (and will!) add their own operations here. Anyway z13 or any later arch will
35 have "SHA-512-DRNG" (3-rd bit of result) and "Query" (0-th bit) functions
36 so we test only this bits and ignore others.
38 static bool test_ppno_query()
40 uint32_t output[4];
41 register uint64_t functionCode __asm__("0") = 0ULL;
42 register uint64_t paramBlock __asm__("1") = (uint64_t) &output;
44 __asm__ volatile (
45 ".insn rre, 0xb93c0000, %%r2, %%r4 \n" // GPR's are ignored here
46 : "+d"(functionCode), "+d"(paramBlock)
48 : "cc", "memory"
51 /* 0x9 = (1 << 0)|(1 << 3), see explanation above */
52 uint32_t expected = 0x90000000U;
53 uint32_t after = output[0];
55 bool result = expected == after;
56 if(!result)
57 printf("ERROR: basic ppno functions are not supported : %d\n", after);
59 return result;
62 static void test_ppno_sha512_seed()
64 /* Important! The program should zero paramBlock for seeding. */
65 memset(block, 0, sizeof(block));
67 uint8_t seed[512];
68 for(size_t index = 0; index < 512; index++)
69 seed[index] = random_element();
70 seed[511] = 0;
71 const uint64_t seedLength = strlen((char*)seed);
73 register uint64_t functionCode __asm__("0") = 0x83ULL;
74 register uint64_t paramBlock __asm__("1") = (uint64_t) &block;
75 register uint64_t gpr2 __asm__("2") = (uint64_t) &seed;
76 register uint64_t gpr3 __asm__("3") = seedLength;
77 __asm__ volatile (
78 ".insn rre, 0xb93c0000, %%r4, %%r2 \n"
80 : "d"(functionCode), "d"(paramBlock), "d"(gpr2), "d"(gpr3)
81 : "cc", "memory"
84 printf("seedLength = %ld\n", seedLength);
85 print_sha512_block();
88 static void test_ppno_sha512_gen()
90 register uint64_t functionCode __asm__("0") = 0x3ULL;
91 register uint64_t paramBlock __asm__("1") = (uint64_t) &block;
92 register uint64_t gpr2 __asm__("2") = (uint64_t) &hash;
93 register uint64_t gpr3 __asm__("3") = HASH_COUNT;
95 __asm__ volatile (
96 "0: .insn rre, 0xb93c0000, %%r2, %%r4 \n"
97 " brc 1, 0 \n" /* handle partial completion */
99 : "d"(functionCode), "d"(paramBlock), "d"(gpr2), "d"(gpr3)
100 : "cc", "memory"
103 print_sha512_hash();
104 print_sha512_block();
107 static void test_ppno_sha512()
109 printf(" === sha512_seed: ===\n");
110 test_ppno_sha512_seed();
111 return;
112 printf(" === sha512_gen: ===\n");
113 test_ppno_sha512_gen();
115 memset(hash, 0, sizeof(hash));
118 int main()
120 size_t iteration;
121 if(!test_ppno_query())
122 return 1;
124 test(ppno_sha512);
126 return 0;