summaryrefslogtreecommitdiff
path: root/src/lib/crypto/builtin/des/f_aead.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/crypto/builtin/des/f_aead.c')
-rw-r--r--src/lib/crypto/builtin/des/f_aead.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/src/lib/crypto/builtin/des/f_aead.c b/src/lib/crypto/builtin/des/f_aead.c
new file mode 100644
index 000000000000..71b8dff4d432
--- /dev/null
+++ b/src/lib/crypto/builtin/des/f_aead.c
@@ -0,0 +1,173 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 2008 by the Massachusetts Institute of Technology.
+ * Copyright 1995 by Richard P. Basch. All Rights Reserved.
+ * Copyright 1995 by Lehman Brothers, Inc. All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. Richard P. Basch,
+ * Lehman Brothers and M.I.T. make no representations about the suitability
+ * of this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ */
+
+#include "crypto_int.h"
+#include "des_int.h"
+#include "f_tables.h"
+
+const mit_des_cblock mit_des_zeroblock /* = all zero */;
+
+void
+krb5int_des_cbc_encrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule schedule,
+ mit_des_cblock ivec)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp;
+ const unsigned char *ip;
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
+
+ /* Get key pointer here. This won't need to be reinitialized. */
+ kp = (const unsigned DES_INT32 *)schedule;
+
+ /* Initialize left and right with the contents of the initial vector. */
+ ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
+ left = load_32_be(ip);
+ right = load_32_be(ip + 4);
+
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
+ /* Decompose this block and xor it with the previous ciphertext. */
+ left ^= load_32_be(block);
+ right ^= load_32_be(block + 4);
+
+ /* Encrypt what we have and put back into block. */
+ DES_DO_ENCRYPT(left, right, kp);
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
+
+ k5_iov_cursor_put(&cursor, block);
+ }
+
+ if (ivec != NULL) {
+ store_32_be(left, ivec);
+ store_32_be(right, ivec + 4);
+ }
+}
+
+void
+krb5int_des_cbc_decrypt(krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule schedule,
+ mit_des_cblock ivec)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp;
+ const unsigned char *ip;
+ unsigned DES_INT32 ocipherl, ocipherr;
+ unsigned DES_INT32 cipherl, cipherr;
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
+
+ /* Get key pointer here. This won't need to be reinitialized. */
+ kp = (const unsigned DES_INT32 *)schedule;
+
+ /*
+ * Decrypting is harder than encrypting because of
+ * the necessity of remembering a lot more things.
+ * Should think about this a little more...
+ */
+
+ /* Prime the old cipher with ivec. */
+ ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
+ ocipherl = load_32_be(ip);
+ ocipherr = load_32_be(ip + 4);
+
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, FALSE);
+ while (k5_iov_cursor_get(&cursor, block)) {
+ /* Split this block into left and right. */
+ cipherl = left = load_32_be(block);
+ cipherr = right = load_32_be(block + 4);
+
+ /* Decrypt and xor with the old cipher to get plain text. */
+ DES_DO_DECRYPT(left, right, kp);
+ left ^= ocipherl;
+ right ^= ocipherr;
+
+ /* Store the encrypted halves back into block. */
+ store_32_be(left, block);
+ store_32_be(right, block + 4);
+
+ /* Save current cipher block halves. */
+ ocipherl = cipherl;
+ ocipherr = cipherr;
+
+ k5_iov_cursor_put(&cursor, block);
+ }
+
+ if (ivec != NULL) {
+ store_32_be(ocipherl, ivec);
+ store_32_be(ocipherr, ivec + 4);
+ }
+}
+
+void
+krb5int_des_cbc_mac(const krb5_crypto_iov *data, unsigned long num_data,
+ const mit_des_key_schedule schedule, mit_des_cblock ivec,
+ mit_des_cblock out)
+{
+ unsigned DES_INT32 left, right;
+ const unsigned DES_INT32 *kp;
+ const unsigned char *ip;
+ struct iov_cursor cursor;
+ unsigned char block[MIT_DES_BLOCK_LENGTH];
+
+ /* Get key pointer here. This won't need to be reinitialized. */
+ kp = (const unsigned DES_INT32 *)schedule;
+
+ /* Initialize left and right with the contents of the initial vector. */
+ ip = (ivec != NULL) ? ivec : mit_des_zeroblock;
+ left = load_32_be(ip);
+ right = load_32_be(ip + 4);
+
+ k5_iov_cursor_init(&cursor, data, num_data, MIT_DES_BLOCK_LENGTH, TRUE);
+ while (k5_iov_cursor_get(&cursor, block)) {
+ /* Decompose this block and xor it with the previous ciphertext. */
+ left ^= load_32_be(block);
+ right ^= load_32_be(block + 4);
+
+ /* Encrypt what we have. */
+ DES_DO_ENCRYPT(left, right, kp);
+ }
+
+ /* Output the final ciphertext block. */
+ store_32_be(left, out);
+ store_32_be(right, out + 4);
+}
+
+#if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
+void krb5int_des_do_encrypt_2 (unsigned DES_INT32 *left,
+ unsigned DES_INT32 *right,
+ const unsigned DES_INT32 *kp)
+{
+ DES_DO_ENCRYPT_1 (*left, *right, kp);
+}
+
+void krb5int_des_do_decrypt_2 (unsigned DES_INT32 *left,
+ unsigned DES_INT32 *right,
+ const unsigned DES_INT32 *kp)
+{
+ DES_DO_DECRYPT_1 (*left, *right, kp);
+}
+#endif