0029-rsync-Add-implementation-of-MD4.patch (12263B)
1 From f6b4408dd3b8ddfa1dca692e1c52643d857d8102 Mon Sep 17 00:00:00 2001 2 From: Michael Forney <mforney@mforney.org> 3 Date: Wed, 15 Apr 2020 22:10:06 -0700 4 Subject: [PATCH] rsync: Add implementation of MD4 5 6 --- 7 usr.bin/rsync/Makefile | 2 +- 8 usr.bin/rsync/blocks.c | 2 +- 9 usr.bin/rsync/downloader.c | 2 +- 10 usr.bin/rsync/extern.h | 3 +- 11 usr.bin/rsync/hash.c | 2 +- 12 usr.bin/rsync/md4.c | 266 +++++++++++++++++++++++++++++++++++++ 13 usr.bin/rsync/md4.h | 47 +++++++ 14 usr.bin/rsync/sender.c | 2 +- 15 8 files changed, 320 insertions(+), 6 deletions(-) 16 create mode 100644 usr.bin/rsync/md4.c 17 create mode 100644 usr.bin/rsync/md4.h 18 19 diff --git a/usr.bin/rsync/Makefile b/usr.bin/rsync/Makefile 20 index 3c60f18e07f..172045ce7ac 100644 21 --- a/usr.bin/rsync/Makefile 22 +++ b/usr.bin/rsync/Makefile 23 @@ -2,7 +2,7 @@ 24 25 PROG= openrsync 26 SRCS= blocks.c client.c copy.c downloader.c fargs.c flist.c hash.c ids.c \ 27 - io.c log.c main.c misc.c mkpath.c mktemp.c receiver.c rmatch.c \ 28 + io.c log.c main.c md4.c misc.c mkpath.c mktemp.c receiver.c rmatch.c \ 29 rules.c sender.c server.c session.c socket.c symlinks.c uploader.c 30 LDADD+= -lcrypto -lm -lutil 31 DPADD+= ${LIBCRYPTO} ${LIBM} ${LIBUTIL} 32 diff --git a/usr.bin/rsync/blocks.c b/usr.bin/rsync/blocks.c 33 index 8f4bcb532e1..f21c9178487 100644 34 --- a/usr.bin/rsync/blocks.c 35 +++ b/usr.bin/rsync/blocks.c 36 @@ -26,7 +26,7 @@ 37 #include <string.h> 38 #include <unistd.h> 39 40 -#include <openssl/md4.h> 41 +#include "md4.h" 42 43 #include "extern.h" 44 45 diff --git a/usr.bin/rsync/downloader.c b/usr.bin/rsync/downloader.c 46 index 07ec334f6b4..6543851fd2c 100644 47 --- a/usr.bin/rsync/downloader.c 48 +++ b/usr.bin/rsync/downloader.c 49 @@ -28,7 +28,7 @@ 50 #include <time.h> 51 #include <unistd.h> 52 53 -#include <openssl/md4.h> 54 +#include "md4.h" 55 56 #include "extern.h" 57 58 diff --git a/usr.bin/rsync/extern.h b/usr.bin/rsync/extern.h 59 index 55d7bc26ae2..d6b02fd4ad4 100644 60 --- a/usr.bin/rsync/extern.h 61 +++ b/usr.bin/rsync/extern.h 62 @@ -19,7 +19,8 @@ 63 64 #include <stdint.h> 65 #include <sys/types.h> 66 -#include <openssl/md4.h> 67 + 68 +#include "md4.h" 69 70 /* 71 * This is the rsync protocol version that we support. 72 diff --git a/usr.bin/rsync/hash.c b/usr.bin/rsync/hash.c 73 index 37529e951b4..e3f52047404 100644 74 --- a/usr.bin/rsync/hash.c 75 +++ b/usr.bin/rsync/hash.c 76 @@ -21,7 +21,7 @@ 77 #include <stdint.h> 78 #include <stdlib.h> 79 80 -#include <openssl/md4.h> 81 +#include "md4.h" 82 83 #include "extern.h" 84 85 diff --git a/usr.bin/rsync/md4.c b/usr.bin/rsync/md4.c 86 new file mode 100644 87 index 00000000000..528f985563f 88 --- /dev/null 89 +++ b/usr.bin/rsync/md4.c 90 @@ -0,0 +1,266 @@ 91 +/* 92 + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 93 + * MD4 Message-Digest Algorithm (RFC 1320). 94 + * 95 + * Homepage: 96 + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 97 + * 98 + * Author: 99 + * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> 100 + * 101 + * This software was written by Alexander Peslyak in 2001. No copyright is 102 + * claimed, and the software is hereby placed in the public domain. 103 + * In case this attempt to disclaim copyright and place the software in the 104 + * public domain is deemed null and void, then the software is 105 + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 106 + * general public under the following terms: 107 + * 108 + * Redistribution and use in source and binary forms, with or without 109 + * modification, are permitted. 110 + * 111 + * There's ABSOLUTELY NO WARRANTY, express or implied. 112 + * 113 + * (This is a heavily cut-down "BSD license".) 114 + * 115 + * This differs from Colin Plumb's older public domain implementation in that 116 + * no exactly 32-bit integer data type is required (any 32-bit or wider 117 + * unsigned integer data type will do), there's no compile-time endianness 118 + * configuration, and the function prototypes match OpenSSL's. No code from 119 + * Colin Plumb's implementation has been reused; this comment merely compares 120 + * the properties of the two independent implementations. 121 + * 122 + * The primary goals of this implementation are portability and ease of use. 123 + * It is meant to be fast, but not as fast as possible. Some known 124 + * optimizations are not included to reduce source code size and avoid 125 + * compile-time configuration. 126 + */ 127 + 128 +#include <string.h> 129 + 130 +#include "md4.h" 131 + 132 +/* 133 + * The basic MD4 functions. 134 + * 135 + * F and G are optimized compared to their RFC 1320 definitions, with the 136 + * optimization for F borrowed from Colin Plumb's MD5 implementation. 137 + */ 138 +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) 139 +#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) 140 +#define H(x, y, z) ((x) ^ (y) ^ (z)) 141 + 142 +/* 143 + * The MD4 transformation for all three rounds. 144 + */ 145 +#define STEP(f, a, b, c, d, x, s) \ 146 + (a) += f((b), (c), (d)) + (x); \ 147 + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); 148 + 149 +/* 150 + * SET reads 4 input bytes in little-endian byte order and stores them in a 151 + * properly aligned word in host byte order. 152 + * 153 + * The check for little-endian architectures that tolerate unaligned memory 154 + * accesses is just an optimization. Nothing will break if it fails to detect 155 + * a suitable architecture. 156 + * 157 + * Unfortunately, this optimization may be a C strict aliasing rules violation 158 + * if the caller's data buffer has effective type that cannot be aliased by 159 + * MD4_u32plus. In practice, this problem may occur if these MD4 routines are 160 + * inlined into a calling function, or with future and dangerously advanced 161 + * link-time optimizations. For the time being, keeping these MD4 routines in 162 + * their own translation unit avoids the problem. 163 + */ 164 +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) 165 +#define SET(n) \ 166 + (*(MD4_u32plus *)&ptr[(n) * 4]) 167 +#define GET(n) \ 168 + SET(n) 169 +#else 170 +#define SET(n) \ 171 + (ctx->block[(n)] = \ 172 + (MD4_u32plus)ptr[(n) * 4] | \ 173 + ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \ 174 + ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \ 175 + ((MD4_u32plus)ptr[(n) * 4 + 3] << 24)) 176 +#define GET(n) \ 177 + (ctx->block[(n)]) 178 +#endif 179 + 180 +/* 181 + * This processes one or more 64-byte data blocks, but does NOT update the bit 182 + * counters. There are no alignment requirements. 183 + */ 184 +static const void *body(MD4_CTX *ctx, const void *data, unsigned long size) 185 +{ 186 + const unsigned char *ptr; 187 + MD4_u32plus a, b, c, d; 188 + MD4_u32plus saved_a, saved_b, saved_c, saved_d; 189 + const MD4_u32plus ac1 = 0x5a827999, ac2 = 0x6ed9eba1; 190 + 191 + ptr = (const unsigned char *)data; 192 + 193 + a = ctx->a; 194 + b = ctx->b; 195 + c = ctx->c; 196 + d = ctx->d; 197 + 198 + do { 199 + saved_a = a; 200 + saved_b = b; 201 + saved_c = c; 202 + saved_d = d; 203 + 204 +/* Round 1 */ 205 + STEP(F, a, b, c, d, SET(0), 3) 206 + STEP(F, d, a, b, c, SET(1), 7) 207 + STEP(F, c, d, a, b, SET(2), 11) 208 + STEP(F, b, c, d, a, SET(3), 19) 209 + STEP(F, a, b, c, d, SET(4), 3) 210 + STEP(F, d, a, b, c, SET(5), 7) 211 + STEP(F, c, d, a, b, SET(6), 11) 212 + STEP(F, b, c, d, a, SET(7), 19) 213 + STEP(F, a, b, c, d, SET(8), 3) 214 + STEP(F, d, a, b, c, SET(9), 7) 215 + STEP(F, c, d, a, b, SET(10), 11) 216 + STEP(F, b, c, d, a, SET(11), 19) 217 + STEP(F, a, b, c, d, SET(12), 3) 218 + STEP(F, d, a, b, c, SET(13), 7) 219 + STEP(F, c, d, a, b, SET(14), 11) 220 + STEP(F, b, c, d, a, SET(15), 19) 221 + 222 +/* Round 2 */ 223 + STEP(G, a, b, c, d, GET(0) + ac1, 3) 224 + STEP(G, d, a, b, c, GET(4) + ac1, 5) 225 + STEP(G, c, d, a, b, GET(8) + ac1, 9) 226 + STEP(G, b, c, d, a, GET(12) + ac1, 13) 227 + STEP(G, a, b, c, d, GET(1) + ac1, 3) 228 + STEP(G, d, a, b, c, GET(5) + ac1, 5) 229 + STEP(G, c, d, a, b, GET(9) + ac1, 9) 230 + STEP(G, b, c, d, a, GET(13) + ac1, 13) 231 + STEP(G, a, b, c, d, GET(2) + ac1, 3) 232 + STEP(G, d, a, b, c, GET(6) + ac1, 5) 233 + STEP(G, c, d, a, b, GET(10) + ac1, 9) 234 + STEP(G, b, c, d, a, GET(14) + ac1, 13) 235 + STEP(G, a, b, c, d, GET(3) + ac1, 3) 236 + STEP(G, d, a, b, c, GET(7) + ac1, 5) 237 + STEP(G, c, d, a, b, GET(11) + ac1, 9) 238 + STEP(G, b, c, d, a, GET(15) + ac1, 13) 239 + 240 +/* Round 3 */ 241 + STEP(H, a, b, c, d, GET(0) + ac2, 3) 242 + STEP(H, d, a, b, c, GET(8) + ac2, 9) 243 + STEP(H, c, d, a, b, GET(4) + ac2, 11) 244 + STEP(H, b, c, d, a, GET(12) + ac2, 15) 245 + STEP(H, a, b, c, d, GET(2) + ac2, 3) 246 + STEP(H, d, a, b, c, GET(10) + ac2, 9) 247 + STEP(H, c, d, a, b, GET(6) + ac2, 11) 248 + STEP(H, b, c, d, a, GET(14) + ac2, 15) 249 + STEP(H, a, b, c, d, GET(1) + ac2, 3) 250 + STEP(H, d, a, b, c, GET(9) + ac2, 9) 251 + STEP(H, c, d, a, b, GET(5) + ac2, 11) 252 + STEP(H, b, c, d, a, GET(13) + ac2, 15) 253 + STEP(H, a, b, c, d, GET(3) + ac2, 3) 254 + STEP(H, d, a, b, c, GET(11) + ac2, 9) 255 + STEP(H, c, d, a, b, GET(7) + ac2, 11) 256 + STEP(H, b, c, d, a, GET(15) + ac2, 15) 257 + 258 + a += saved_a; 259 + b += saved_b; 260 + c += saved_c; 261 + d += saved_d; 262 + 263 + ptr += 64; 264 + } while (size -= 64); 265 + 266 + ctx->a = a; 267 + ctx->b = b; 268 + ctx->c = c; 269 + ctx->d = d; 270 + 271 + return ptr; 272 +} 273 + 274 +void MD4_Init(MD4_CTX *ctx) 275 +{ 276 + ctx->a = 0x67452301; 277 + ctx->b = 0xefcdab89; 278 + ctx->c = 0x98badcfe; 279 + ctx->d = 0x10325476; 280 + 281 + ctx->lo = 0; 282 + ctx->hi = 0; 283 +} 284 + 285 +void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size) 286 +{ 287 + MD4_u32plus saved_lo; 288 + unsigned long used, available; 289 + 290 + saved_lo = ctx->lo; 291 + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) 292 + ctx->hi++; 293 + ctx->hi += size >> 29; 294 + 295 + used = saved_lo & 0x3f; 296 + 297 + if (used) { 298 + available = 64 - used; 299 + 300 + if (size < available) { 301 + memcpy(&ctx->buffer[used], data, size); 302 + return; 303 + } 304 + 305 + memcpy(&ctx->buffer[used], data, available); 306 + data = (const unsigned char *)data + available; 307 + size -= available; 308 + body(ctx, ctx->buffer, 64); 309 + } 310 + 311 + if (size >= 64) { 312 + data = body(ctx, data, size & ~(unsigned long)0x3f); 313 + size &= 0x3f; 314 + } 315 + 316 + memcpy(ctx->buffer, data, size); 317 +} 318 + 319 +#define OUT(dst, src) \ 320 + (dst)[0] = (unsigned char)(src); \ 321 + (dst)[1] = (unsigned char)((src) >> 8); \ 322 + (dst)[2] = (unsigned char)((src) >> 16); \ 323 + (dst)[3] = (unsigned char)((src) >> 24); 324 + 325 +void MD4_Final(unsigned char *result, MD4_CTX *ctx) 326 +{ 327 + unsigned long used, available; 328 + 329 + used = ctx->lo & 0x3f; 330 + 331 + ctx->buffer[used++] = 0x80; 332 + 333 + available = 64 - used; 334 + 335 + if (available < 8) { 336 + memset(&ctx->buffer[used], 0, available); 337 + body(ctx, ctx->buffer, 64); 338 + used = 0; 339 + available = 64; 340 + } 341 + 342 + memset(&ctx->buffer[used], 0, available - 8); 343 + 344 + ctx->lo <<= 3; 345 + OUT(&ctx->buffer[56], ctx->lo) 346 + OUT(&ctx->buffer[60], ctx->hi) 347 + 348 + body(ctx, ctx->buffer, 64); 349 + 350 + OUT(&result[0], ctx->a) 351 + OUT(&result[4], ctx->b) 352 + OUT(&result[8], ctx->c) 353 + OUT(&result[12], ctx->d) 354 + 355 + memset(ctx, 0, sizeof(*ctx)); 356 +} 357 diff --git a/usr.bin/rsync/md4.h b/usr.bin/rsync/md4.h 358 new file mode 100644 359 index 00000000000..ebf5bb555a0 360 --- /dev/null 361 +++ b/usr.bin/rsync/md4.h 362 @@ -0,0 +1,47 @@ 363 +/* 364 + * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 365 + * MD4 Message-Digest Algorithm (RFC 1320). 366 + * 367 + * Homepage: 368 + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md4 369 + * 370 + * Author: 371 + * Alexander Peslyak, better known as Solar Designer <solar at openwall.com> 372 + * 373 + * This software was written by Alexander Peslyak in 2001. No copyright is 374 + * claimed, and the software is hereby placed in the public domain. 375 + * In case this attempt to disclaim copyright and place the software in the 376 + * public domain is deemed null and void, then the software is 377 + * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 378 + * general public under the following terms: 379 + * 380 + * Redistribution and use in source and binary forms, with or without 381 + * modification, are permitted. 382 + * 383 + * There's ABSOLUTELY NO WARRANTY, express or implied. 384 + * 385 + * See md4.c for more information. 386 + */ 387 + 388 +#ifndef _MD4_H 389 +#define _MD4_H 390 + 391 +#include <stdint.h> 392 + 393 +#define MD4_DIGEST_LENGTH 16 394 + 395 +/* Any 32-bit or wider unsigned integer data type will do */ 396 +typedef uint_fast32_t MD4_u32plus; 397 + 398 +typedef struct { 399 + MD4_u32plus lo, hi; 400 + MD4_u32plus a, b, c, d; 401 + unsigned char buffer[64]; 402 + MD4_u32plus block[16]; 403 +} MD4_CTX; 404 + 405 +extern void MD4_Init(MD4_CTX *ctx); 406 +extern void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size); 407 +extern void MD4_Final(unsigned char *result, MD4_CTX *ctx); 408 + 409 +#endif 410 diff --git a/usr.bin/rsync/sender.c b/usr.bin/rsync/sender.c 411 index 6469e7f27e5..81b25b9ee78 100644 412 --- a/usr.bin/rsync/sender.c 413 +++ b/usr.bin/rsync/sender.c 414 @@ -26,7 +26,7 @@ 415 #include <string.h> 416 #include <unistd.h> 417 418 -#include <openssl/md4.h> 419 +#include "md4.h" 420 421 #include "extern.h" 422 423 -- 424 2.49.0 425