aboutsummaryrefslogtreecommitdiffstats
path: root/toolchain/glibc/patches/050-Revert-Disallow-use-of-DES-encryption-functions-in-n.patch
blob: 10d9f65d18dffa3b0f180062946fff4813de9feb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
From 08f5e0df46ce1ad617bcde1fd5542545397630b9 Mon Sep 17 00:00:00 2001
From: Hans Dedecker <dedeckeh@gmail.com>
Date: Sat, 24 Oct 2020 21:13:30 +0200
Subject: Revert "Disallow use of DES encryption functions in new programs."

This reverts commit b10a0accee709a5efff2fadf0b0bbb79ff0ad759.

ppp still uses the encrypt functions from the libc while musl libc also
provides them.
---
 conform/data/stdlib.h-data |   3 +
 conform/data/unistd.h-data |   6 ++
 crypt/cert.c               |  26 -----
 crypt/crypt-entry.c        |  15 ++-
 crypt/crypt.h              |  16 +++
 crypt/crypt_util.c         |   9 --
 manual/conf.texi           |   2 -
 manual/crypt.texi          | 204 +++++++++++++++++++++++++++++++++++++
 manual/string.texi         |  82 +++++++--------
 posix/unistd.h             |  17 +++-
 stdlib/stdlib.h            |   6 ++
 sunrpc/des_crypt.c         |   7 +-
 sunrpc/des_soft.c          |   2 +-
 13 files changed, 305 insertions(+), 90 deletions(-)

--- a/conform/data/stdlib.h-data
+++ b/conform/data/stdlib.h-data
@@ -149,6 +149,9 @@ function {unsigned short int*} seed48 (u
 #if !defined ISO && !defined ISO99 && !defined ISO11 && !defined POSIX && !defined XPG4 && !defined XPG42 && !defined UNIX98
 function int setenv (const char*, const char*, int)
 #endif
+#if !defined ISO && !defined ISO99 && !defined ISO11 && !defined POSIX && !defined POSIX2008
+function void setkey (const char*)
+#endif
 #if !defined ISO && !defined ISO99 && !defined ISO11 && !defined XPG4 && !defined POSIX && !defined POSIX2008
 function {char*} setstate (char*)
 #endif
--- a/conform/data/unistd.h-data
+++ b/conform/data/unistd.h-data
@@ -437,6 +437,9 @@ function int chroot (const char*)
 function int chown (const char*, uid_t, gid_t)
 function int close (int)
 function size_t confstr (int, char*, size_t)
+#if !defined POSIX && !defined POSIX2008
+function {char*} crypt (const char*, const char*)
+#endif
 #if defined XPG4 || defined XPG42 || defined UNIX98
 function {char*} ctermid (char*)
 function {char*} cuserid (char*)
@@ -446,6 +449,9 @@ allow cuserid
 #endif
 function int dup (int)
 function int dup2 (int, int)
+#if !defined POSIX && !defined POSIX2008
+function void encrypt (char[64], int)
+#endif
 function int execl (const char*, const char*, ...)
 function int execle (const char*, const char*, ...)
 function int execlp (const char*, const char*, ...)
--- a/crypt/cert.c
+++ b/crypt/cert.c
@@ -10,22 +10,6 @@
 #include <stdlib.h>
 #include "crypt.h"
 
-/* This file tests the deprecated setkey/encrypt interface.  */
-#include <shlib-compat.h>
-#if TEST_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
-
-#define libcrypt_version_reference(symbol, version) \
-  _libcrypt_version_reference (symbol, VERSION_libcrypt_##version)
-#define _libcrypt_version_reference(symbol, version) \
-  __libcrypt_version_reference (symbol, version)
-#define __libcrypt_version_reference(symbol, version) \
-  __asm__ (".symver " #symbol ", " #symbol "@" #version)
-
-extern void setkey (const char *);
-extern void encrypt (const char *, int);
-libcrypt_version_reference (setkey, GLIBC_2_0);
-libcrypt_version_reference (encrypt, GLIBC_2_0);
-
 int totfails = 0;
 
 int main (int argc, char *argv[]);
@@ -120,13 +104,3 @@ put8 (char *cp)
 	  printf("%02x", t);
 	}
 }
-
-#else /* encrypt and setkey are not available.  */
-
-int
-main (void)
-{
-  return 77; /* UNSUPPORTED */
-}
-
-#endif
--- a/crypt/crypt-entry.c
+++ b/crypt/crypt-entry.c
@@ -35,7 +35,6 @@
 #endif
 
 #include "crypt-private.h"
-#include <shlib-compat.h>
 
 /* Prototypes for local functions.  */
 #ifndef __GNU_LIBRARY__
@@ -177,7 +176,17 @@ crypt (const char *key, const char *salt
   return __crypt_r (key, salt, &_ufc_foobar);
 }
 
-#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
+
+/*
+ * To make fcrypt users happy.
+ * They don't need to call init_des.
+ */
+#ifdef _LIBC
 weak_alias (crypt, fcrypt)
-compat_symbol (libcrypt, fcrypt, fcrypt, GLIBC_2_0);
+#else
+char *
+__fcrypt (const char *key, const char *salt)
+{
+  return crypt (key, salt);
+}
 #endif
--- a/crypt/crypt.h
+++ b/crypt/crypt.h
@@ -36,6 +36,14 @@ __BEGIN_DECLS
 extern char *crypt (const char *__phrase, const char *__salt)
      __THROW __nonnull ((1, 2));
 
+/* Setup DES tables according KEY.  */
+extern void setkey (const char *__key) __THROW __nonnull ((1));
+
+/* Encrypt data in BLOCK in place if EDFLAG is zero; otherwise decrypt
+   block in place.  */
+extern void encrypt (char *__glibc_block, int __edflag)
+     __THROW __nonnull ((1));
+
 #ifdef __USE_GNU
 
 /* This structure provides scratch and output buffers for 'crypt_r'.
@@ -63,6 +71,14 @@ struct crypt_data
 extern char *crypt_r (const char *__phrase, const char *__salt,
 		      struct crypt_data * __restrict __data)
      __THROW __nonnull ((1, 2, 3));
+
+extern void setkey_r (const char *__key,
+		      struct crypt_data * __restrict __data)
+     __THROW __nonnull ((1, 2));
+
+extern void encrypt_r (char *__glibc_block, int __edflag,
+		       struct crypt_data * __restrict __data)
+     __THROW __nonnull ((1, 3));
 #endif
 
 __END_DECLS
--- a/crypt/crypt_util.c
+++ b/crypt/crypt_util.c
@@ -34,7 +34,6 @@
 #endif
 
 #include "crypt-private.h"
-#include <shlib-compat.h>
 
 /* Prototypes for local functions.  */
 #ifndef __GNU_LIBRARY__
@@ -151,7 +150,6 @@ static const int sbox[8][4][16]= {
 	}
 };
 
-#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
 /*
  * This is the initial
  * permutation matrix
@@ -162,7 +160,6 @@ static const int initial_perm[64] = {
   57, 49, 41, 33, 25, 17,  9,  1, 59, 51, 43, 35, 27, 19, 11, 3,
   61, 53, 45, 37, 29, 21, 13,  5, 63, 55, 47, 39, 31, 23, 15, 7
 };
-#endif
 
 /*
  * This is the final
@@ -788,7 +785,6 @@ _ufc_output_conversion_r (ufc_long v1, u
   __data->crypt_3_buf[13] = 0;
 }
 
-#if SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28)
 
 /*
  * UNIX encrypt function. Takes a bitvector
@@ -889,14 +885,12 @@ __encrypt_r (char *__block, int __edflag
   }
 }
 weak_alias (__encrypt_r, encrypt_r)
-compat_symbol (libcrypt, encrypt_r, encrypt_r, GLIBC_2_0);
 
 void
 encrypt (char *__block, int __edflag)
 {
   __encrypt_r(__block, __edflag, &_ufc_foobar);
 }
-compat_symbol (libcrypt, encrypt, encrypt, GLIBC_2_0);
 
 
 /*
@@ -921,15 +915,12 @@ __setkey_r (const char *__key, struct cr
   _ufc_mk_keytab_r((char *) ktab, __data);
 }
 weak_alias (__setkey_r, setkey_r)
-compat_symbol (libcrypt, setkey_r, setkey_r, GLIBC_2_0);
 
 void
 setkey (const char *__key)
 {
   __setkey_r(__key, &_ufc_foobar);
 }
-compat_symbol (libcrypt, setkey, setkey, GLIBC_2_0);
-#endif /* SHLIB_COMPAT (libcrypt, GLIBC_2_0, GLIBC_2_28) */
 
 void
 __b64_from_24bit (char **cp, int *buflen,
--- a/manual/conf.texi
+++ b/manual/conf.texi
@@ -780,8 +780,6 @@ Inquire about the parameter correspondin
 @item _SC_XOPEN_CRYPT
 @standards{X/Open, unistd.h}
 Inquire about the parameter corresponding to @code{_XOPEN_CRYPT}.
-@Theglibc no longer implements the @code{_XOPEN_CRYPT} extensions,
-so @samp{sysconf (_SC_XOPEN_CRYPT)} always returns @code{-1}.
 
 @item _SC_XOPEN_ENH_I18N
 @standards{X/Open, unistd.h}
--- a/manual/crypt.texi
+++ b/manual/crypt.texi
@@ -16,8 +16,19 @@ subject to them, even if you do not use
 yourself.  The restrictions vary from place to place and are changed
 often, so we cannot give any more specific advice than this warning.
 
+@vindex AUTH_DES
+@cindex FIPS 140-2
+It also provides support for Secure RPC, and some library functions that
+can be used to perform normal DES encryption.  The @code{AUTH_DES}
+authentication flavor in Secure RPC, as provided by @theglibc{},
+uses DES and does not comply with FIPS 140-2 nor does any other use of DES
+within @theglibc{}.  It is recommended that Secure RPC should not be used
+for systems that need to comply with FIPS 140-2 since all flavors of
+encrypted authentication use normal DES.
+
 @menu
 * Passphrase Storage::          One-way hashing for passphrases.
+* crypt::                       A one-way function for passwords.
 * Unpredictable Bytes::         Randomness for cryptographic purposes.
 @end menu
 
@@ -190,6 +201,199 @@ unpredictable as possible; @pxref{Unpred
 @include genpass.c.texi
 @end smallexample
 
+@node DES Encryption
+@section DES Encryption
+
+@cindex FIPS 46-3
+The Data Encryption Standard is described in the US Government Federal
+Information Processing Standards (FIPS) 46-3 published by the National
+Institute of Standards and Technology.  The DES has been very thoroughly
+analyzed since it was developed in the late 1970s, and no new
+significant flaws have been found.
+
+However, the DES uses only a 56-bit key (plus 8 parity bits), and a
+machine has been built in 1998 which can search through all possible
+keys in about 6 days, which cost about US$200000; faster searches would
+be possible with more money.  This makes simple DES insecure for most
+purposes, and NIST no longer permits new US government systems
+to use simple DES.
+
+For serious encryption functionality, it is recommended that one of the
+many free encryption libraries be used instead of these routines.
+
+The DES is a reversible operation which takes a 64-bit block and a
+64-bit key, and produces another 64-bit block.  Usually the bits are
+numbered so that the most-significant bit, the first bit, of each block
+is numbered 1.
+
+Under that numbering, every 8th bit of the key (the 8th, 16th, and so
+on) is not used by the encryption algorithm itself.  But the key must
+have odd parity; that is, out of bits 1 through 8, and 9 through 16, and
+so on, there must be an odd number of `1' bits, and this completely
+specifies the unused bits.
+
+@deftypefun void setkey (const char *@var{key})
+@standards{BSD, crypt.h}
+@standards{SVID, crypt.h}
+@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
+@c The static buffer stores the key, making it fundamentally
+@c thread-unsafe.  The locking issues are only in the initialization
+@c path; cancelling the initialization will leave the lock held, it
+@c would otherwise repeat the initialization on the next call.
+
+The @code{setkey} function sets an internal data structure to be an
+expanded form of @var{key}.  @var{key} is specified as an array of 64
+bits each stored in a @code{char}, the first bit is @code{key[0]} and
+the 64th bit is @code{key[63]}.  The @var{key} should have the correct
+parity.
+@end deftypefun
+
+@deftypefun void encrypt (char *@var{block}, int @var{edflag})
+@standards{BSD, crypt.h}
+@standards{SVID, crypt.h}
+@safety{@prelim{}@mtunsafe{@mtasurace{:crypt}}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
+@c Same issues as setkey.
+
+The @code{encrypt} function encrypts @var{block} if
+@var{edflag} is 0, otherwise it decrypts @var{block}, using a key
+previously set by @code{setkey}.  The result is
+placed in @var{block}.
+
+Like @code{setkey}, @var{block} is specified as an array of 64 bits each
+stored in a @code{char}, but there are no parity bits in @var{block}.
+@end deftypefun
+
+@deftypefun void setkey_r (const char *@var{key}, {struct crypt_data *} @var{data})
+@deftypefunx void encrypt_r (char *@var{block}, int @var{edflag}, {struct crypt_data *} @var{data})
+@standards{GNU, crypt.h}
+@c setkey_r: @safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
+@safety{@prelim{}@mtsafe{}@asunsafe{@asucorrupt{} @asulock{}}@acunsafe{@aculock{}}}
+
+These are reentrant versions of @code{setkey} and @code{encrypt}.  The
+only difference is the extra parameter, which stores the expanded
+version of @var{key}.  Before calling @code{setkey_r} the first time,
+@code{data->initialized} must be cleared to zero.
+@end deftypefun
+
+The @code{setkey_r} and @code{encrypt_r} functions are GNU extensions.
+@code{setkey}, @code{encrypt}, @code{setkey_r}, and @code{encrypt_r} are
+defined in @file{crypt.h}.
+
+@deftypefun int ecb_crypt (char *@var{key}, char *@var{blocks}, unsigned int @var{len}, unsigned int @var{mode})
+@standards{SUNRPC, rpc/des_crypt.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+The function @code{ecb_crypt} encrypts or decrypts one or more blocks
+using DES.  Each block is encrypted independently.
+
+The @var{blocks} and the @var{key} are stored packed in 8-bit bytes, so
+that the first bit of the key is the most-significant bit of
+@code{key[0]} and the 63rd bit of the key is stored as the
+least-significant bit of @code{key[7]}.  The @var{key} should have the
+correct parity.
+
+@var{len} is the number of bytes in @var{blocks}.  It should be a
+multiple of 8 (so that there are a whole number of blocks to encrypt).
+@var{len} is limited to a maximum of @code{DES_MAXDATA} bytes.
+
+The result of the encryption replaces the input in @var{blocks}.
+
+The @var{mode} parameter is the bitwise OR of two of the following:
+
+@vtable @code
+@item DES_ENCRYPT
+@standards{SUNRPC, rpc/des_crypt.h}
+This constant, used in the @var{mode} parameter, specifies that
+@var{blocks} is to be encrypted.
+
+@item DES_DECRYPT
+@standards{SUNRPC, rpc/des_crypt.h}
+This constant, used in the @var{mode} parameter, specifies that
+@var{blocks} is to be decrypted.
+
+@item DES_HW
+@standards{SUNRPC, rpc/des_crypt.h}
+This constant, used in the @var{mode} parameter, asks to use a hardware
+device.  If no hardware device is available, encryption happens anyway,
+but in software.
+
+@item DES_SW
+@standards{SUNRPC, rpc/des_crypt.h}
+This constant, used in the @var{mode} parameter, specifies that no
+hardware device is to be used.
+@end vtable
+
+The result of the function will be one of these values:
+
+@vtable @code
+@item DESERR_NONE
+@standards{SUNRPC, rpc/des_crypt.h}
+The encryption succeeded.
+
+@item DESERR_NOHWDEVICE
+@standards{SUNRPC, rpc/des_crypt.h}
+The encryption succeeded, but there was no hardware device available.
+
+@item DESERR_HWERROR
+@standards{SUNRPC, rpc/des_crypt.h}
+The encryption failed because of a hardware problem.
+
+@item DESERR_BADPARAM
+@standards{SUNRPC, rpc/des_crypt.h}
+The encryption failed because of a bad parameter, for instance @var{len}
+is not a multiple of 8 or @var{len} is larger than @code{DES_MAXDATA}.
+@end vtable
+@end deftypefun
+
+@deftypefun int DES_FAILED (int @var{err})
+@standards{SUNRPC, rpc/des_crypt.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+This macro returns 1 if @var{err} is a `success' result code from
+@code{ecb_crypt} or @code{cbc_crypt}, and 0 otherwise.
+@end deftypefun
+
+@deftypefun int cbc_crypt (char *@var{key}, char *@var{blocks}, unsigned int @var{len}, unsigned int @var{mode}, char *@var{ivec})
+@standards{SUNRPC, rpc/des_crypt.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+The function @code{cbc_crypt} encrypts or decrypts one or more blocks
+using DES in Cipher Block Chaining mode.
+
+For encryption in CBC mode, each block is exclusive-ored with @var{ivec}
+before being encrypted, then @var{ivec} is replaced with the result of
+the encryption, then the next block is processed.  Decryption is the
+reverse of this process.
+
+This has the advantage that blocks which are the same before being
+encrypted are very unlikely to be the same after being encrypted, making
+it much harder to detect patterns in the data.
+
+Usually, @var{ivec} is set to 8 random bytes before encryption starts.
+Then the 8 random bytes are transmitted along with the encrypted data
+(without themselves being encrypted), and passed back in as @var{ivec}
+for decryption.  Another possibility is to set @var{ivec} to 8 zeroes
+initially, and have the first block encrypted consist of 8 random
+bytes.
+
+Otherwise, all the parameters are similar to those for @code{ecb_crypt}.
+@end deftypefun
+
+@deftypefun void des_setparity (char *@var{key})
+@standards{SUNRPC, rpc/des_crypt.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+The function @code{des_setparity} changes the 64-bit @var{key}, stored
+packed in 8-bit bytes, to have odd parity by altering the low bits of
+each byte.
+@end deftypefun
+
+The @code{ecb_crypt}, @code{cbc_crypt}, and @code{des_setparity}
+functions and their accompanying macros are all defined in the header
+@file{rpc/des_crypt.h}.
+
+@node Unpredictable Bytes
+@section Generating Unpredictable Bytes
+
 The next program demonstrates how to verify a passphrase.  It checks a
 hash hardcoded into the program, because looking up real users' hashed
 passphrases may require special privileges (@pxref{User Database}).
--- a/manual/string.texi
+++ b/manual/string.texi
@@ -36,8 +36,8 @@ too.
 				 for delimiters.
 * Erasing Sensitive Data::      Clearing memory which contains sensitive
                                  data, after it's no longer needed.
-* Shuffling Bytes::             Or how to flash-cook a string.
-* Obfuscating Data::            Reversibly obscuring data from casual view.
+* strfry::                      Function for flash-cooking a string.
+* Trivial Encryption::          Obscuring data.
 * Encode Binary Data::          Encoding and Decoding of Binary Data.
 * Argz and Envz Vectors::       Null-separated string vectors.
 @end menu
@@ -2426,73 +2426,73 @@ functionality under a different name, su
 systems it may be in @file{strings.h} instead.
 @end deftypefun
 
-
-@node Shuffling Bytes
-@section Shuffling Bytes
+@node strfry
+@section strfry
 
 The function below addresses the perennial programming quandary: ``How do
 I take good data in string form and painlessly turn it into garbage?''
-This is not a difficult thing to code for oneself, but the authors of
-@theglibc{} wish to make it as convenient as possible.
+This is actually a fairly simple task for C programmers who do not use
+@theglibc{} string functions, but for programs based on @theglibc{},
+the @code{strfry} function is the preferred method for
+destroying string data.
 
-To @emph{erase} data, use @code{explicit_bzero} (@pxref{Erasing
-Sensitive Data}); to obfuscate it reversibly, use @code{memfrob}
-(@pxref{Obfuscating Data}).
+The prototype for this function is in @file{string.h}.
 
 @deftypefun {char *} strfry (char *@var{string})
 @standards{GNU, string.h}
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 @c Calls initstate_r, time, getpid, strlen, and random_r.
 
-@code{strfry} performs an in-place shuffle on @var{string}.  Each
-character is swapped to a position selected at random, within the
-portion of the string starting with the character's original position.
-(This is the Fisher-Yates algorithm for unbiased shuffling.)
-
-Calling @code{strfry} will not disturb any of the random number
-generators that have global state (@pxref{Pseudo-Random Numbers}).
+@code{strfry} creates a pseudorandom anagram of a string, replacing the
+input with the anagram in place.  For each position in the string,
+@code{strfry} swaps it with a position in the string selected at random
+(from a uniform distribution).  The two positions may be the same.
 
 The return value of @code{strfry} is always @var{string}.
 
 @strong{Portability Note:}  This function is unique to @theglibc{}.
-It is declared in @file{string.h}.
+
 @end deftypefun
 
 
-@node Obfuscating Data
-@section Obfuscating Data
+@node Trivial Encryption
+@section Trivial Encryption
+@cindex encryption
+
+
+The @code{memfrob} function converts an array of data to something
+unrecognizable and back again.  It is not encryption in its usual sense
+since it is easy for someone to convert the encrypted data back to clear
+text.  The transformation is analogous to Usenet's ``Rot13'' encryption
+method for obscuring offensive jokes from sensitive eyes and such.
+Unlike Rot13, @code{memfrob} works on arbitrary binary data, not just
+text.
 @cindex Rot13
 
-The @code{memfrob} function reversibly obfuscates an array of binary
-data.  This is not true encryption; the obfuscated data still bears a
-clear relationship to the original, and no secret key is required to
-undo the obfuscation.  It is analogous to the ``Rot13'' cipher used on
-Usenet for obscuring offensive jokes, spoilers for works of fiction,
-and so on, but it can be applied to arbitrary binary data.
-
-Programs that need true encryption---a transformation that completely
-obscures the original and cannot be reversed without knowledge of a
-secret key---should use a dedicated cryptography library, such as
-@uref{https://www.gnu.org/software/libgcrypt/,,libgcrypt}.
-
-Programs that need to @emph{destroy} data should use
-@code{explicit_bzero} (@pxref{Erasing Sensitive Data}), or possibly
-@code{strfry} (@pxref{Shuffling Bytes}).
+For true encryption, @xref{Cryptographic Functions}.
+
+This function is declared in @file{string.h}.
+@pindex string.h
 
 @deftypefun {void *} memfrob (void *@var{mem}, size_t @var{length})
 @standards{GNU, string.h}
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 
-The function @code{memfrob} obfuscates @var{length} bytes of data
-beginning at @var{mem}, in place.  Each byte is bitwise xor-ed with
-the binary pattern 00101010 (hexadecimal 0x2A).  The return value is
-always @var{mem}.
-
-@code{memfrob} a second time on the same data returns it to
-its original state.
+@code{memfrob} transforms (frobnicates) each byte of the data structure
+at @var{mem}, which is @var{length} bytes long, by bitwise exclusive
+oring it with binary 00101010.  It does the transformation in place and
+its return value is always @var{mem}.
+
+Note that @code{memfrob} a second time on the same data structure
+returns it to its original state.
+
+This is a good function for hiding information from someone who doesn't
+want to see it or doesn't want to see it very much.  To really prevent
+people from retrieving the information, use stronger encryption such as
+that described in @xref{Cryptographic Functions}.
 
 @strong{Portability Note:}  This function is unique to @theglibc{}.
-It is declared in @file{string.h}.
+
 @end deftypefun
 
 @node Encode Binary Data
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -107,6 +107,9 @@ __BEGIN_DECLS
 /* The X/Open Unix extensions are available.  */
 #define _XOPEN_UNIX	1
 
+/* Encryption is present.  */
+#define	_XOPEN_CRYPT	1
+
 /* The enhanced internationalization capabilities according to XPG4.2
    are present.  */
 #define	_XOPEN_ENH_I18N	1
@@ -1129,17 +1132,25 @@ ssize_t copy_file_range (int __infd, __o
 extern int fdatasync (int __fildes);
 #endif /* Use POSIX199309 */
 
-#ifdef __USE_MISC
+/* XPG4.2 specifies that prototypes for the encryption functions must
+   be defined here.  */
+#ifdef	__USE_XOPEN
 /* One-way hash PHRASE, returning a string suitable for storage in the
    user database.  SALT selects the one-way function to use, and
    ensures that no two users' hashes are the same, even if they use
    the same passphrase.  The return value points to static storage
    which will be overwritten by the next call to crypt.  */
+
+/* Encrypt at most 8 characters from KEY using salt to perturb DES.  */
 extern char *crypt (const char *__key, const char *__salt)
      __THROW __nonnull ((1, 2));
-#endif
 
-#ifdef	__USE_XOPEN
+/* Encrypt data in BLOCK in place if EDFLAG is zero; otherwise decrypt
+   block in place.  */
+extern void encrypt (char *__glibc_block, int __edflag)
+     __THROW __nonnull ((1));
+
+
 /* Swab pairs bytes in the first N bytes of the area pointed to by
    FROM and copy the result to TO.  The value of TO must not be in the
    range [FROM - N + 1, FROM - 1].  If N is odd the first byte in FROM
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -962,6 +962,12 @@ extern int getsubopt (char **__restrict
 #endif
 
 
+#ifdef __USE_XOPEN
+/* Setup DES tables according KEY.  */
+extern void setkey (const char *__key) __THROW __nonnull ((1));
+#endif
+
+
 /* X/Open pseudo terminal handling.  */
 
 #ifdef __USE_XOPEN2KXSI
--- a/sunrpc/des_crypt.c
+++ b/sunrpc/des_crypt.c
@@ -86,9 +86,6 @@ common_crypt (char *key, char *buf, regi
   return desdev == DES_SW ? DESERR_NONE : DESERR_NOHWDEVICE;
 }
 
-/* Note: these cannot be excluded from the build yet, because they are
-   still used internally.  */
-
 /*
  * CBC mode encryption
  */
@@ -105,7 +102,7 @@ cbc_crypt (char *key, char *buf, unsigne
   COPY8 (dp.des_ivec, ivec);
   return err;
 }
-hidden_nolink (cbc_crypt, libc, GLIBC_2_1)
+libc_hidden_nolink_sunrpc (cbc_crypt, GLIBC_2_1)
 
 /*
  * ECB mode encryption
@@ -118,4 +115,4 @@ ecb_crypt (char *key, char *buf, unsigne
   dp.des_mode = ECB;
   return common_crypt (key, buf, len, mode, &dp);
 }
-hidden_nolink (ecb_crypt, libc, GLIBC_2_1)
+libc_hidden_nolink_sunrpc (ecb_crypt, GLIBC_2_1)
--- a/sunrpc/des_soft.c
+++ b/sunrpc/des_soft.c
@@ -71,4 +71,4 @@ des_setparity (char *p)
       p++;
     }
 }
-hidden_nolink (des_setparity, libc, GLIBC_2_1)
+libc_hidden_nolink_sunrpc (des_setparity, GLIBC_2_1)