summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2004-02-13 12:44:15 +0000
committerWerner Koch <wk@gnupg.org>2004-02-13 12:44:15 +0000
commit9ae6fbadb25da203bbb4504f3db5fb0dd9da40d8 (patch)
tree32af00840636be1c62a7d9cd58a262b596f9f31f
parent9f271b48a775e8c26416d6dd32b5df722a5ff567 (diff)
downloadlibgcrypt-9ae6fbadb25da203bbb4504f3db5fb0dd9da40d8.tar.gz
Added support for a 40 bit RFC2268 cipher. Thanks to Nikos.
-rw-r--r--AUTHORS4
-rw-r--r--ChangeLog8
-rw-r--r--NEWS8
-rwxr-xr-xautogen.sh2
-rw-r--r--cipher/ChangeLog7
-rw-r--r--cipher/Makefile.am3
-rw-r--r--cipher/Manifest7
-rw-r--r--cipher/cipher.c3
-rw-r--r--cipher/des.c2
-rw-r--r--cipher/rfc2268.c345
-rw-r--r--configure.ac9
-rw-r--r--src/ChangeLog9
-rw-r--r--src/cipher.h1
-rw-r--r--src/gcrypt.h10
14 files changed, 407 insertions, 11 deletions
diff --git a/AUTHORS b/AUTHORS
index c07e0491..e22a26a8 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -58,6 +58,10 @@ LIBGCRYPT Moritz Schulte 2003-04-17
Assigns past and future changes.
moritz@g10code.com
+GNUTLS Nikolaos Mavrogiannopoulos 2003-11-22
+nmav@gnutls.org
+Orginal code for cipher/rfc2268.c.
+
More credits
diff --git a/ChangeLog b/ChangeLog
index 3213d6fa..741d1acf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2004-02-11 Werner Koch <wk@gnupg.org>
+
+ * autogen.sh (check_version): Removed bashism and simplified.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Add rfc2268 cipher algorithm.
+
2004-01-25 Moritz Schulte <mo@g10code.com>
* THANKS: Updated.
diff --git a/NEWS b/NEWS
index ed8001cf..1f2b3808 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,14 @@
Noteworthy changes in version 1.1.92 (unreleased)
-------------------------------------------------
+ * Minor bug fixes.
+
+ * Included a limited implementation of RFC2268.
+
+ * Interface changes relative to the 1.1.91 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GCRY_CIPHER_RFC2268_40 NEW.
+
Noteworthy changes in version 1.1.91 (2003-12-19)
-------------------------------------------------
diff --git a/autogen.sh b/autogen.sh
index 4f1205c6..81061e38 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -18,7 +18,7 @@ cvtver () {
}
check_version () {
- if [ $(( `("$1" --version || echo "0") | cvtver` >= $2 )) == 1 ]; then
+ if [ `("$1" --version || echo "0") | cvtver` -ge "$2" ]; then
return 0
fi
echo "**Error**: "\`$1\'" not installed or too old." >&2
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index 1621e26e..cabb83a7 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,3 +1,10 @@
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * des.c: Add a new OID as used by pkcs#12.
+
+ * rfc2268.c: New. Taken from libgcrypt.
+ * cipher.c: Setup the rfc2268 algorithm.
+
2004-01-25 Moritz Schulte <mo@g10code.com>
* primegen.c (prime_generate_internal): Do not forget to free
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 8df81fef..cf38060f 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -62,7 +62,8 @@ sha1.c \
sha256.c \
sha512.c \
tiger.c \
-twofish.c
+twofish.c \
+rfc2268.c
# We need to lower the optimization for this module.
tiger.o: $(srcdir)/tiger.c
diff --git a/cipher/Manifest b/cipher/Manifest
index e173019d..e5fc4672 100644
--- a/cipher/Manifest
+++ b/cipher/Manifest
@@ -39,7 +39,7 @@ arcfour.c iQCVAwUAP9XR/TEAnp832S/7AQJcRwP6AlvYEx++fpT4mIYo0xRDqKEQeqMQvbaRhIg2eV
blowfish.c iQCVAwUAP9XTETEAnp832S/7AQJaEgQAgiqqfuO+zQtscgTB0rvOzVymIKjRKjYhFuLjVuc79G4z1RCAffvIn/YM2d7kt+Z/QF7zjcTAOgETCQL1XokpX2zz9HPAMi2tlDY5zsDufTNqj0n4WBL9nM7w6XAvsiwP1B3bqCTv9SjJV4KbxJ58vw1yQE+sqW74R/QIHFvC7mU==wZnX
cast5.c iQCVAwUAP9XT6DEAnp832S/7AQJ3xgP/ehLjEN3GELGudbqeo91Xd+PqitHrkuBbtRIYX7Udd/fyXLN+h8rMJVyIQX2m+mpxbBxudVU3x8/DNT8B0ZHAwK6qqJmEBLLhEYPgIuF76i9LMrP1KqUPhAwRZ2OppjIIugBQ+rP74aD4eLyd/aKQHNuXML8QGWR6KwQShohXM5I==/BRh
crc.c iQCVAwUAP7ouejEAnp832S/7AQIgwQQApg5Nm63tH5DQkbN+zPzMO9Ygoj3ukxfFTyTBPYSXYKMiTjEbESegaU40uN8jnz2vprcIQWcgZfzO4+opEJMcI35aPwzEk0vKOp0S/PrBLUY2rJfnDVkX5XgJFZa2Q7LLe826UEBzTVYW924utiCCe8oOaOEWVNpg1mqdknu3M9o==kz5D
-des.c iQCVAwUAP9XWVDEAnp832S/7AQLjYgP8DTVwIS1L/eODK2HOCuJgIqAg1MS9Jpb1w56pKM4pOQ24mH/pMWUgksntW1PqGXRzqt66k+AFw200/AujbEcEmB4kTmMRVYIDUrextWXsg8AQUaUqxPD6pP0mq2Y6afhCgaRm0rAYDz2kI2RRRxHPyRhwi/j+TNke01AdnnK1k2A==xGcy
+des.c iQCVAwUAQCN2oDEAnp832S/7AQL/jwP6Auoq6nZCDBjpgc9tDzuIRwa9DqyuM3gX94uvgEpUwdHszb2bG43dz03kVmcYxtj1MzXbyCeCZOwox0b2SKmLgxIbrNP6yGbzVdTj6592gDYuf/ZXmc1ZNJ1DDldcPQ0n9fXUipUPwyPaNWo3mSZaNcMKSWWzdK0J6ciG6nk7SWI==9k/t
dsa.c iQCVAwUAP9XZHDEAnp832S/7AQLBRgP/XrBzTEYx5ccMj1MMb6sg37liEHdIyyy49zjvt6jUqxj4RuwVEN8S6v3u4q/QyJkHAi1E0EkREgENlyHW6PKWhYbcrd0vPIAN15yjnl2yqtrCrJImexUCoqJJewK0E4JOicGbabTil8MZjk+mbhEPnjJBqOkyP1w0i31pEDgE/8M==pC8s
elgamal.c iQCVAwUAP9XbYzEAnp832S/7AQLXagQA3HrvspZfbTGgmUH0IqLQTJ0exUPxJv5DET2TvoIy62trDmMN6lTAj5P+a7jQ8udcu0w+mR2vXUHcxUpNA2PxLaMwGzNSY4zRDNe9r3SFTDrFm6m4y9Ko2e8XtEA+WF6P/XLpck4Jn7vMEDmVGPwkNd22kXFFE8dBGwG6i5Hk1Mk==oBUs
md4.c iQCVAwUAP9h50DEAnp832S/7AQJhHgQAzNA/B6MWFDlCtPkIVaW8RpP1Eg0ZNMsy0s7SJkopOCBlu6CwXUOKe+8ppcSxhjYKh4i4uQr/QtfipYlBjzKJGnrafoF/NugXNCOHSTGT11TvK7mCiBuUMVgvZGAlOJImk6eTTfUjRrMfaXM/SWl8bdJ4ZpzdjEyVh89r7I5JrGk==x2UD
@@ -53,6 +53,7 @@ sha256.c iQCVAwUAP9iAtzEAnp832S/7AQJD2QP/UqvL0hhjG1wEFbGrdkV9tba1sMDXdnnK6X7HdLu
sha512.c iQCVAwUAP9iBTDEAnp832S/7AQIPBAQA28CJSUQLiW0s2x9u8/OH2eKnxPjA4sZmb50WP7920Lem66P31C3BrOqwfBot4RLhjL+zh/+Uc4s3HPwApZuj9E4BxNMlqLv+Tqk++DAbdaOeYT4jeUt+mlhQQ6mH/RDsy32rZsNsGQ2bUGxazZmfG++PL3JyhawqCy00SUDr/o0==H+0X
tiger.c iQCVAwUAP9iCfjEAnp832S/7AQKufwP/fryv3MqSOYY+90325DH7X3/CtekxeooN0scGsHX0fxBakWSMecTNrj33KPddLS46gU/S89zIc2N/Bw/7EVIAXVFA3/3Ip+OrFOuIMO4Py1sCdB8o2Y+5ygv8iXLcsXIq1O0av79i9g774V3uaXa2qN9ZnXe0AEhcy8FHJ2i/wro==5XVB
twofish.c iQCVAwUAP9iD6TEAnp832S/7AQKUnQP/Rq8FaYeHTG7HbZuqAs9pbPitzjDbkdZddmInWR7NmevBkKvhsJALjVooc0KGQfo2lAAmy3Xi/4QQN8VPn51DVjDIgf7x+DQh/9TFJHMccxI9asUgi4+TNnmMqLU1k3N8S2PjyZ1sjeC8B79fKPpwCzj72WkqPkzZw3l2jArr+dU==NdJT
+rfc2268.c iQCVAwUAQCN+3jEAnp832S/7AQLv1gQA1hJh29hAjKi4uLSGxXvJ6cyYmPdmevdKrbLnuHZWtHe4xvCgy/nTdEojEpxgLp/hL/ogasuWRC1W16Wiz9ryxf7YR0uhZWayO/bQNagpfU5MIkJTLuKqqgpwYumCSQfOugXVAqcgEzj+13eeyJaFVrzwrNa67sh84nmbjOjNjvE==0zBq
# Random number related
random.c iQCVAwUAP7nsITEAnp832S/7AQK4SAQAtvfUgrtGOQ2PlxGMla0qJLPHjJacMwgq0ecusiI79elPdDsFfCCk6dK1Ug2kFbNm22nCGHNcUquqbX7noi7ZVQnmPBQXzyLNZd7GmrawRZfdlRerTUDBpSnR8V8ui/5+YYp627E7kKGC0hPSgqXFql6oBMIfno0LZwFJTjIevRY==L419
@@ -68,5 +69,5 @@ bithelp.h iQCVAwUAP7ouPTEAnp832S/7AQKXggQAqjcgvihIF3WclOgw1JV2rbARw4ISIDRMFqdaNC
rmd.h iQCVAwUAP7oumjEAnp832S/7AQJiJQP/V4bJwjZaYndJzV+KRnIDbl1koHuw+ZK5heMYVu8Qk4ylqv//BGyeRa3jZCcfPHI35q6HilCs2VBm8hiBMjHSqY/VPn2ZQ0yg/lt6qEvl7YjsLmyMICvjG+ncszHoq9pRvnF3vTnM18sPIioXLk8fskuM0XOCNBs0ARBAQjY9UGI==olUN
# Configuration
-Makefile.am iQCVAwUAP+M6vTEAnp832S/7AQK6iAP/bupnOKllxgd4Wz/vpHE5cLtTrvZoioRFvtLKvFDtukwQccadeSUGdtJRJT6tm8E+60UTmyZZGJu/XeBM3jrN3YoNVB5kTL0EA4P3iBUiNm40QFIb7l0KaFMauFIWch68sWapflg0Mv7f+T8uFt3tdxWDrXe/xYLQzs2Udplo7Ow==F6NE
-$names$ iQCVAwUAP99DTTEAnp832S/7AQL3ugP/SvLX71fTqDrfpUqw+XXhEUWCYQ80U+CQBsZTsAsXvK/F1476dHkJIDco64ZXv/cWwL4AmUYHhXC3uFXhQmFW8qyCXOYr5s3THgjzld1gqzRoVSwa5d8ZEhHXgIY8cnz3G3kwUksXGZioMER7LCWVudyLMNOLW9yOc2sBZqrvGn0==wlNe
+Makefile.am iQCVAwUAQCN33TEAnp832S/7AQKFJAQAz7BDkC814q+QiuE/jnutJHR5qlgbrm3ikGbQwdRzYUscst4bCCWy3uKL/sIPGLg+JQXtF5FnsQy3s4D9BOYhp72cA9ktYK65hhi4pNm/JQ0lXkZMNfk8Go5lNzKezlWwHvkMwRXR0Fep0wPdyeaKW5BfaW2ABvgep6Bp+hHEbyg==zSyi
+$names$ iQCVAwUAQCN3EDEAnp832S/7AQJXLAP8DvHTpm5DkTF35EmzeKpi9ie59AZcZanD19ir/e/7+PaQxr2riuLHDGwFKTju+dcvvBsqrygXOC378GXVWzIF2OZwS4EdDcJ+pgojo9UpsqpKsJHouY4Ugx5cQialxba462kUn8hcihSBnMyc4LzbJ5WQ4puQuqy544d2x94+2ms==G4Ls
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 2c290814..16f57f43 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -69,6 +69,9 @@ static struct cipher_table_entry
{ &_gcry_cipher_spec_serpent192, GCRY_CIPHER_SERPENT192 },
{ &_gcry_cipher_spec_serpent256, GCRY_CIPHER_SERPENT256 },
#endif
+#ifdef USE_RFC2268
+ { &_gcry_cipher_spec_rfc2268_40, GCRY_CIPHER_RFC2268_40 },
+#endif
{ NULL },
};
diff --git a/cipher/des.c b/cipher/des.c
index a0d98263..81b5337e 100644
--- a/cipher/des.c
+++ b/cipher/des.c
@@ -1099,6 +1099,8 @@ static gcry_cipher_oid_spec_t oids_tripledes[] =
{ "1.2.840.113549.3.7", GCRY_CIPHER_MODE_CBC },
/* Teletrust specific OID for 3DES. */
{ "1.3.36.3.1.3.2.1", GCRY_CIPHER_MODE_CBC },
+ /* pbeWithSHAAnd3_KeyTripleDES_CBC */
+ { "1.2.840.113549.1.12.1.3", GCRY_CIPHER_MODE_CBC },
{ NULL }
};
diff --git a/cipher/rfc2268.c b/cipher/rfc2268.c
new file mode 100644
index 00000000..7d63fcef
--- /dev/null
+++ b/cipher/rfc2268.c
@@ -0,0 +1,345 @@
+/* rfc2268.c - The cipher described in rfc2268; aka Ron's Cipher 2.
+ * Copyright (C) 2003 Nikos Mavroyanopoulos
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
+ * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
+ * direct use by Libgcrypt by Werner Koch. This implementation is
+ * only useful for pkcs#12 descryption.
+ *
+ * The implementation here is based on Peter Gutmann's RRC.2 paper.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g10lib.h"
+#include "types.h"
+#include "cipher.h"
+
+#define RFC2268_BLOCKSIZE 8
+
+typedef struct
+{
+ u16 S[64];
+} RFC2268_context;
+
+static const unsigned char rfc2268_sbox[] = {
+ 217, 120, 249, 196, 25, 221, 181, 237,
+ 40, 233, 253, 121, 74, 160, 216, 157,
+ 198, 126, 55, 131, 43, 118, 83, 142,
+ 98, 76, 100, 136, 68, 139, 251, 162,
+ 23, 154, 89, 245, 135, 179, 79, 19,
+ 97, 69, 109, 141, 9, 129, 125, 50,
+ 189, 143, 64, 235, 134, 183, 123, 11,
+ 240, 149, 33, 34, 92, 107, 78, 130,
+ 84, 214, 101, 147, 206, 96, 178, 28,
+ 115, 86, 192, 20, 167, 140, 241, 220,
+ 18, 117, 202, 31, 59, 190, 228, 209,
+ 66, 61, 212, 48, 163, 60, 182, 38,
+ 111, 191, 14, 218, 70, 105, 7, 87,
+ 39, 242, 29, 155, 188, 148, 67, 3,
+ 248, 17, 199, 246, 144, 239, 62, 231,
+ 6, 195, 213, 47, 200, 102, 30, 215,
+ 8, 232, 234, 222, 128, 82, 238, 247,
+ 132, 170, 114, 172, 53, 77, 106, 42,
+ 150, 26, 210, 113, 90, 21, 73, 116,
+ 75, 159, 208, 94, 4, 24, 164, 236,
+ 194, 224, 65, 110, 15, 81, 203, 204,
+ 36, 145, 175, 80, 161, 244, 112, 57,
+ 153, 124, 58, 133, 35, 184, 180, 122,
+ 252, 2, 54, 91, 37, 85, 151, 49,
+ 45, 93, 250, 152, 227, 138, 146, 174,
+ 5, 223, 41, 16, 103, 108, 186, 201,
+ 211, 0, 230, 207, 225, 158, 168, 44,
+ 99, 22, 1, 63, 88, 226, 137, 169,
+ 13, 56, 52, 27, 171, 51, 255, 176,
+ 187, 72, 12, 95, 185, 177, 205, 46,
+ 197, 243, 219, 71, 229, 165, 156, 119,
+ 10, 166, 32, 104, 254, 127, 193, 173
+};
+
+#define rotl16(x,n) (((x) << ((u16)(n))) | ((x) >> (16 - (u16)(n))))
+#define rotr16(x,n) (((x) >> ((u16)(n))) | ((x) << (16 - (u16)(n))))
+
+static const char *selftest (void);
+
+
+static void
+do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ RFC2268_context *ctx = context;
+ register int i, j;
+ u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
+
+ word0 = (word0 << 8) | inbuf[1];
+ word0 = (word0 << 8) | inbuf[0];
+ word1 = (word1 << 8) | inbuf[3];
+ word1 = (word1 << 8) | inbuf[2];
+ word2 = (word2 << 8) | inbuf[5];
+ word2 = (word2 << 8) | inbuf[4];
+ word3 = (word3 << 8) | inbuf[7];
+ word3 = (word3 << 8) | inbuf[6];
+
+ for (i = 0; i < 16; i++)
+ {
+ j = i * 4;
+ /* For some reason I cannot combine those steps. */
+ word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j];
+ word0 = rotl16(word0, 1);
+
+ word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
+ word1 = rotl16(word1, 2);
+
+ word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
+ word2 = rotl16(word2, 3);
+
+ word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
+ word3 = rotl16(word3, 5);
+
+ if (i == 4 || i == 10)
+ {
+ word0 += ctx->S[word3 & 63];
+ word1 += ctx->S[word0 & 63];
+ word2 += ctx->S[word1 & 63];
+ word3 += ctx->S[word2 & 63];
+ }
+
+ }
+
+ outbuf[0] = word0 & 255;
+ outbuf[1] = word0 >> 8;
+ outbuf[2] = word1 & 255;
+ outbuf[3] = word1 >> 8;
+ outbuf[4] = word2 & 255;
+ outbuf[5] = word2 >> 8;
+ outbuf[6] = word3 & 255;
+ outbuf[7] = word3 >> 8;
+}
+
+static void
+do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ RFC2268_context *ctx = context;
+ register int i, j;
+ u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
+
+ word0 = (word0 << 8) | inbuf[1];
+ word0 = (word0 << 8) | inbuf[0];
+ word1 = (word1 << 8) | inbuf[3];
+ word1 = (word1 << 8) | inbuf[2];
+ word2 = (word2 << 8) | inbuf[5];
+ word2 = (word2 << 8) | inbuf[4];
+ word3 = (word3 << 8) | inbuf[7];
+ word3 = (word3 << 8) | inbuf[6];
+
+ for (i = 15; i >= 0; i--)
+ {
+ j = i * 4;
+
+ word3 = rotr16(word3, 5);
+ word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
+
+ word2 = rotr16(word2, 3);
+ word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
+
+ word1 = rotr16(word1, 2);
+ word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
+
+ word0 = rotr16(word0, 1);
+ word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j];
+
+ if (i == 5 || i == 11)
+ {
+ word3 = word3 - ctx->S[word2 & 63];
+ word2 = word2 - ctx->S[word1 & 63];
+ word1 = word1 - ctx->S[word0 & 63];
+ word0 = word0 - ctx->S[word3 & 63];
+ }
+
+ }
+
+ outbuf[0] = word0 & 255;
+ outbuf[1] = word0 >> 8;
+ outbuf[2] = word1 & 255;
+ outbuf[3] = word1 >> 8;
+ outbuf[4] = word2 & 255;
+ outbuf[5] = word2 >> 8;
+ outbuf[6] = word3 & 255;
+ outbuf[7] = word3 >> 8;
+}
+
+
+static gpg_err_code_t
+setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2)
+{
+ static int initialized;
+ static const char *selftest_failed;
+ RFC2268_context *ctx = context;
+ unsigned int i;
+ unsigned char *S, x;
+ int len;
+ int bits = keylen * 8;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+ if (selftest_failed)
+ log_error ("RFC2268 selftest failed (%s).\n", selftest_failed);
+ }
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ if (keylen < 40 / 8) /* We want at least 40 bits. */
+ return GPG_ERR_INV_KEYLEN;
+
+ S = (unsigned char *) ctx->S;
+
+ for (i = 0; i < keylen; i++)
+ S[i] = key[i];
+
+ for (i = keylen; i < 128; i++)
+ S[i] = rfc2268_sbox[(S[i - keylen] + S[i - 1]) & 255];
+
+ S[0] = rfc2268_sbox[S[0]];
+
+ /* Phase 2 - reduce effective key size to "bits". This was not
+ * discussed in Gutmann's paper. I've copied that from the public
+ * domain code posted in sci.crypt. */
+ if (with_phase2)
+ {
+ len = (bits + 7) >> 3;
+ i = 128 - len;
+ x = rfc2268_sbox[S[i] & (255 >> (7 & -bits))];
+ S[i] = x;
+
+ while (i--)
+ {
+ x = rfc2268_sbox[x ^ S[i + len]];
+ S[i] = x;
+ }
+ }
+
+ /* Make the expanded key, endian independent. */
+ for (i = 0; i < 64; i++)
+ ctx->S[i] = ( (u16) S[i * 2] | (((u16) S[i * 2 + 1]) << 8));
+
+ return 0;
+}
+
+static gpg_err_code_t
+do_setkey (void *context, const unsigned char *key, unsigned int keylen)
+{
+ return setkey_core (context, key, keylen, 1);
+}
+
+static const char *
+selftest (void)
+{
+ RFC2268_context ctx;
+ unsigned char scratch[16];
+
+ /* Test vectors from Peter Gutmann's paper. */
+ static unsigned char key_1[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static unsigned char plaintext_1[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const unsigned char ciphertext_1[] =
+ { 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 };
+
+ static unsigned char key_2[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+ };
+ static unsigned char plaintext_2[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static unsigned char ciphertext_2[] =
+ { 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 };
+
+ /* This one was checked against libmcrypt's RFC2268. */
+ static unsigned char key_3[] =
+ { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static unsigned char plaintext_3[] =
+ { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static unsigned char ciphertext_3[] =
+ { 0x8f, 0xd1, 0x03, 0x89, 0x33, 0x6b, 0xf9, 0x5e };
+
+
+ /* First test. */
+ setkey_core (&ctx, key_1, sizeof(key_1), 0);
+ do_encrypt (&ctx, scratch, plaintext_1);
+
+ if (memcmp (scratch, ciphertext_1, sizeof(ciphertext_1)))
+ return "RFC2268 encryption test 1 failed.";
+
+ setkey_core (&ctx, key_1, sizeof(key_1), 0);
+ do_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_1, sizeof(plaintext_1)))
+ return "RFC2268 decryption test 1 failed.";
+
+ /* Second test. */
+ setkey_core (&ctx, key_2, sizeof(key_2), 0);
+ do_encrypt (&ctx, scratch, plaintext_2);
+ if (memcmp (scratch, ciphertext_2, sizeof(ciphertext_2)))
+ return "RFC2268 encryption test 2 failed.";
+
+ setkey_core (&ctx, key_2, sizeof(key_2), 0);
+ do_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_2, sizeof(plaintext_2)))
+ return "RFC2268 decryption test 2 failed.";
+
+ /* Third test. */
+ setkey_core(&ctx, key_3, sizeof(key_3), 0);
+ do_encrypt(&ctx, scratch, plaintext_3);
+
+ if (memcmp(scratch, ciphertext_3, sizeof(ciphertext_3)))
+ return "RFC2268 encryption test 3 failed.";
+
+ setkey_core (&ctx, key_3, sizeof(key_3), 0);
+ do_decrypt (&ctx, scratch, scratch);
+ if (memcmp(scratch, plaintext_3, sizeof(plaintext_3)))
+ return "RFC2268 decryption test 3 failed.";
+
+ return NULL;
+}
+
+
+
+static gcry_cipher_oid_spec_t oids_rfc2268_40[] =
+ {
+ /*{ "1.2.840.113549.3.2", GCRY_CIPHER_MODE_CBC },*/
+ /* pbeWithSHAAnd40BitRC2_CBC */
+ { "1.2.840.113549.1.12.1.6", GCRY_CIPHER_MODE_CBC },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = {
+ "RFC2268_40", NULL, oids_rfc2268_40,
+ RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
+ do_setkey, do_encrypt, do_decrypt
+};
+
diff --git a/configure.ac b/configure.ac
index beebeaa8..572b3247 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
# Configure.ac script for Libgcrypt
# Copyright (C) 1998, 1999, 2000, 2001, 2002
-# 2003 Free Software Foundation, Inc.
+# 2003, 2004 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
@@ -88,7 +88,7 @@ LIBGCRYPT_CONFIG_LIBS_PTH="-lgcrypt-pth"
LIBGCRYPT_CONFIG_CFLAGS_PTH=""
# Definitions for symmetric ciphers.
-available_ciphers="arcfour blowfish cast5 des aes twofish serpent"
+available_ciphers="arcfour blowfish cast5 des aes twofish serpent rfc2268"
enabled_ciphers=""
# Definitions for public-key ciphers.
@@ -714,6 +714,11 @@ test "$found" = "1" && GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent.lo"
AC_DEFINE_UNQUOTED(USE_SERPENT, $found,
[Defined if this module should be included])
+LIST_MEMBER(rfc2268, $enabled_ciphers)
+test "$found" = "1" && GCRYPT_CIPHERS="$GCRYPT_CIPHERS rfc2268.lo"
+AC_DEFINE_UNQUOTED(USE_RFC2268, $found,
+ [Defined if this module should be included])
+
LIST_MEMBER(dsa, $enabled_pubkey_ciphers)
test "$found" = "1" && GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS dsa.lo"
AC_DEFINE_UNQUOTED(USE_DSA, $found,
diff --git a/src/ChangeLog b/src/ChangeLog
index e2f50c29..6b8a3166 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
+2004-02-13 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRY_CIPHER_RFC2268_128, alsthough not yet
+ supported.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRY_CIPHER_RFC2268_40.
+
2004-02-03 Werner Koch <wk@gnupg.org>
* secmem.c (_gcry_secmem_init): Do not print the "not locked into
diff --git a/src/cipher.h b/src/cipher.h
index bcb7095f..a5f194e9 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -57,6 +57,7 @@ extern gcry_cipher_spec_t _gcry_cipher_spec_twofish128;
extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128;
extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192;
extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40;
/* Declarations for the digest specifications. */
extern gcry_md_spec_t _gcry_digest_spec_crc32;
diff --git a/src/gcrypt.h b/src/gcrypt.h
index 4ec0e77b..3c607cdd 100644
--- a/src/gcrypt.h
+++ b/src/gcrypt.h
@@ -1,5 +1,6 @@
/* gcrypt.h - GNU cryptographic library interface
- * Copyright (C) 1998,1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
+ * 2004 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -596,14 +597,15 @@ enum gcry_cipher_algos
GCRY_CIPHER_AES256 = 9,
GCRY_CIPHER_TWOFISH = 10,
- /* other cipher numbers are above 300 for OpenPGP reasons. */
- GCRY_CIPHER_ARCFOUR = 301, /* fully compatible with RSA's RC4 (tm). */
+ /* Other cipher numbers are above 300 for OpenPGP reasons. */
+ GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */
GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */
GCRY_CIPHER_TWOFISH128 = 303,
GCRY_CIPHER_SERPENT128 = 304,
GCRY_CIPHER_SERPENT192 = 305,
GCRY_CIPHER_SERPENT256 = 306,
-
+ GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */
+ GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */
};
/* The Rijndael algorithm is basically AES, so provide some macros. */