Rizin
unix-like reverse engineering framework and cli tools
randomart.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 1995 Tatu Ylonen <ylo@cs.hut.fi>
2 // SPDX-FileCopyrightText: 2000, 2001 Markus Friedl
3 // SPDX-License-Identifier: BSD-2-Clause
4 
5 /*
6  * This code is originally taken from OpenSSH:
7  * http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/key.c?rev=1.75&content-type=text/x-cvsweb-markup
8  */
9 
10 /*
11  * Draw an ASCII-Art representing the fingerprint so human brain can
12  * profit from its built-in pattern recognition ability.
13  * This technique is called "random art" and can be found in some
14  * scientific publications like this original paper:
15  *
16  * "Hash Visualization: a New Technique to improve Real-World Security",
17  * Perrig A. and Song D., 1999, International Workshop on Cryptographic
18  * Techniques and E-Commerce (CrypTEC '99)
19  * sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf
20  *
21  * The subject came up in a talk by Dan Kaminsky, too.
22  *
23  * If you see the picture is different, the key is different.
24  * If the picture looks the same, you still know nothing.
25  *
26  * The algorithm used here is a worm crawling over a discrete plane,
27  * leaving a trace (augmenting the field) everywhere it goes.
28  * Movement is taken from buffer 2bit-wise. Bumping into walls
29  * makes the respective movement vector be ignored for this turn.
30  * Graphs are not unambiguous, because circles in graphs can be
31  * walked in either direction.
32  */
33 
34 /*
35  * Field sizes for the random art. Have to be odd, so the starting point
36  * can be in the exact middle of the picture, and FLDBASE should be >=8 .
37  * Else pictures would be too dense, and drawing the frame would
38  * fail, too, because the key type would not fit in anymore.
39  */
40 #include <rz_hash.h>
41 #include <rz_util.h>
42 
43 #define FLDBASE 8
44 #define FLDSIZE_Y (FLDBASE + 1)
45 #define FLDSIZE_X (FLDBASE * 2 + 1)
46 
57  /*
58  * Chars to be used after each other every time the worm
59  * intersects with itself. Matter of taste.
60  */
61  char *augmentation_string = " .o+=*BOX@%&#/^SE";
62  char *retval, *p;
63  ut8 field[FLDSIZE_X][FLDSIZE_Y];
64  ut32 i, b;
65  int x, y;
66  size_t len = strlen(augmentation_string) - 1;
67 
68  // 2*(FLDSIZE_X+3) there are two for loops that iterate over this
69  // FLDSIZE_Y * (FLDSIZE_X+3) there is a loop that for each y iterates over the whole FLDSIZE_X
70  // The rest is counting the +--[0x%08"PFMT64x"]- and '\0'
71  retval = calloc(1, 2 * (FLDSIZE_X + 3) + (FLDSIZE_Y * (FLDSIZE_X + 3)) + 7 + sizeof(PFMT64x));
72  if (!retval) {
73  return NULL;
74  }
75 
76  /* initialize field */
77  memset(field, 0, FLDSIZE_X * FLDSIZE_Y * sizeof(char));
78  x = FLDSIZE_X / 2;
79  y = FLDSIZE_Y / 2;
80 
81  /* process raw key */
82  for (i = 0; i < length; i++) {
83  int input;
84  /* each byte conveys four 2-bit move commands */
85  input = buffer[i];
86  for (b = 0; b < 4; b++) {
87  /* evaluate 2 bit, rest is shifted later */
88  x += (input & 0x1) ? 1 : -1;
89  y += (input & 0x2) ? 1 : -1;
90 
91  /* assure we are still in bounds */
92  x = RZ_MAX(x, 0);
93  y = RZ_MAX(y, 0);
94  x = RZ_MIN(x, FLDSIZE_X - 1);
95  y = RZ_MIN(y, FLDSIZE_Y - 1);
96 
97  /* augment the field */
98  if (field[x][y] < len - 2) {
99  field[x][y]++;
100  }
101  input = input >> 2;
102  }
103  }
104 
105  /* mark starting point and end point*/
106  field[FLDSIZE_X / 2][FLDSIZE_Y / 2] = len - 1;
107  field[x][y] = len;
108 
109  /* fill in retval */
110  sprintf(retval, "+--[0x%08" PFMT64x "]-", address);
111  p = strchr(retval, '\0');
112 
113  /* output upper border */
114  for (i = p - retval - 1; i < FLDSIZE_X; i++) {
115  *p++ = '-';
116  }
117  *p++ = '+';
118  *p++ = '\n';
119 
120  /* output content */
121  for (y = 0; y < FLDSIZE_Y; y++) {
122  *p++ = '|';
123  for (x = 0; x < FLDSIZE_X; x++) {
124  *p++ = augmentation_string[RZ_MIN(field[x][y], len)];
125  }
126  *p++ = '|';
127  *p++ = '\n';
128  }
129 
130  /* output lower border */
131  *p++ = '+';
132  for (i = 0; i < FLDSIZE_X; i++) {
133  *p++ = '-';
134  }
135  *p++ = '+';
136  *p++ = 0;
137 
138  return retval;
139 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
uint32_t ut32
sprintf
Definition: kernel.h:365
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
int x
Definition: mipsasm.c:20
RZ_API RZ_OWN char * rz_hash_cfg_randomart(RZ_NONNULL const ut8 *buffer, ut32 length, ut64 address)
Generates a randomart that is meant to be an easily validate buffers.
Definition: randomart.c:55
#define FLDSIZE_X
Definition: randomart.c:45
#define FLDSIZE_Y
Definition: randomart.c:44
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NONNULL
Definition: rz_types.h:64
#define PFMT64x
Definition: rz_types.h:393
#define RZ_MIN(x, y)
#define RZ_MAX(x, y)
#define b(i)
Definition: sha256.c:42
Definition: buffer.h:15
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)