1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci/*
11e1051a39Sopenharmony_ci * From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer IEEE
12e1051a39Sopenharmony_ci * Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40 This module in
13e1051a39Sopenharmony_ci * only based on the code in this paper and is almost definitely not the same
14e1051a39Sopenharmony_ci * as the MIT implementation.
15e1051a39Sopenharmony_ci */
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ci/*
18e1051a39Sopenharmony_ci * DES low level APIs are deprecated for public use, but still ok for internal
19e1051a39Sopenharmony_ci * use.
20e1051a39Sopenharmony_ci */
21e1051a39Sopenharmony_ci#include "internal/deprecated.h"
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_ci#include "des_local.h"
24e1051a39Sopenharmony_ci
25e1051a39Sopenharmony_ci#define Q_B0(a) (((DES_LONG)(a)))
26e1051a39Sopenharmony_ci#define Q_B1(a) (((DES_LONG)(a))<<8)
27e1051a39Sopenharmony_ci#define Q_B2(a) (((DES_LONG)(a))<<16)
28e1051a39Sopenharmony_ci#define Q_B3(a) (((DES_LONG)(a))<<24)
29e1051a39Sopenharmony_ci
30e1051a39Sopenharmony_ci/* used to scramble things a bit */
31e1051a39Sopenharmony_ci/* Got the value MIT uses via brute force :-) 2/10/90 eay */
32e1051a39Sopenharmony_ci#define NOISE   ((DES_LONG)83653421L)
33e1051a39Sopenharmony_ci
34e1051a39Sopenharmony_ciDES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[],
35e1051a39Sopenharmony_ci                        long length, int out_count, DES_cblock *seed)
36e1051a39Sopenharmony_ci{
37e1051a39Sopenharmony_ci    DES_LONG z0, z1, t0, t1;
38e1051a39Sopenharmony_ci    int i;
39e1051a39Sopenharmony_ci    long l;
40e1051a39Sopenharmony_ci    const unsigned char *cp;
41e1051a39Sopenharmony_ci    DES_LONG *lp;
42e1051a39Sopenharmony_ci
43e1051a39Sopenharmony_ci    if (out_count < 1)
44e1051a39Sopenharmony_ci        out_count = 1;
45e1051a39Sopenharmony_ci    lp = (DES_LONG *)&(output[0])[0];
46e1051a39Sopenharmony_ci
47e1051a39Sopenharmony_ci    z0 = Q_B0((*seed)[0]) | Q_B1((*seed)[1]) | Q_B2((*seed)[2]) |
48e1051a39Sopenharmony_ci        Q_B3((*seed)[3]);
49e1051a39Sopenharmony_ci    z1 = Q_B0((*seed)[4]) | Q_B1((*seed)[5]) | Q_B2((*seed)[6]) |
50e1051a39Sopenharmony_ci        Q_B3((*seed)[7]);
51e1051a39Sopenharmony_ci
52e1051a39Sopenharmony_ci    for (i = 0; ((i < 4) && (i < out_count)); i++) {
53e1051a39Sopenharmony_ci        cp = input;
54e1051a39Sopenharmony_ci        l = length;
55e1051a39Sopenharmony_ci        while (l > 0) {
56e1051a39Sopenharmony_ci            if (l > 1) {
57e1051a39Sopenharmony_ci                t0 = (DES_LONG)(*(cp++));
58e1051a39Sopenharmony_ci                t0 |= (DES_LONG)Q_B1(*(cp++));
59e1051a39Sopenharmony_ci                l--;
60e1051a39Sopenharmony_ci            } else
61e1051a39Sopenharmony_ci                t0 = (DES_LONG)(*(cp++));
62e1051a39Sopenharmony_ci            l--;
63e1051a39Sopenharmony_ci            /* add */
64e1051a39Sopenharmony_ci            t0 += z0;
65e1051a39Sopenharmony_ci            t0 &= 0xffffffffL;
66e1051a39Sopenharmony_ci            t1 = z1;
67e1051a39Sopenharmony_ci            /* square, well sort of square */
68e1051a39Sopenharmony_ci            z0 = ((((t0 * t0) & 0xffffffffL) + ((t1 * t1) & 0xffffffffL))
69e1051a39Sopenharmony_ci                  & 0xffffffffL) % 0x7fffffffL;
70e1051a39Sopenharmony_ci            z1 = ((t0 * ((t1 + NOISE) & 0xffffffffL)) & 0xffffffffL) %
71e1051a39Sopenharmony_ci                0x7fffffffL;
72e1051a39Sopenharmony_ci        }
73e1051a39Sopenharmony_ci        if (lp != NULL) {
74e1051a39Sopenharmony_ci            /*
75e1051a39Sopenharmony_ci             * The MIT library assumes that the checksum is composed of
76e1051a39Sopenharmony_ci             * 2*out_count 32 bit ints
77e1051a39Sopenharmony_ci             */
78e1051a39Sopenharmony_ci            *lp++ = z0;
79e1051a39Sopenharmony_ci            *lp++ = z1;
80e1051a39Sopenharmony_ci        }
81e1051a39Sopenharmony_ci    }
82e1051a39Sopenharmony_ci    return z0;
83e1051a39Sopenharmony_ci}
84