• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /*
11  * MD2 low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <openssl/crypto.h>
20 #include <openssl/des.h>
21 #include <openssl/mdc2.h>
22 
23 #undef c2l
24 #define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
25                          l|=((DES_LONG)(*((c)++)))<< 8L, \
26                          l|=((DES_LONG)(*((c)++)))<<16L, \
27                          l|=((DES_LONG)(*((c)++)))<<24L)
28 
29 #undef l2c
30 #define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
31                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
32                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
33                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
34 
35 static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
MDC2_Init(MDC2_CTX * c)36 int MDC2_Init(MDC2_CTX *c)
37 {
38     c->num = 0;
39     c->pad_type = 1;
40     memset(&(c->h[0]), 0x52, MDC2_BLOCK);
41     memset(&(c->hh[0]), 0x25, MDC2_BLOCK);
42     return 1;
43 }
44 
MDC2_Update(MDC2_CTX * c,const unsigned char * in,size_t len)45 int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len)
46 {
47     size_t i, j;
48 
49     i = c->num;
50     if (i != 0) {
51         if (len < MDC2_BLOCK - i) {
52             /* partial block */
53             memcpy(&(c->data[i]), in, len);
54             c->num += (int)len;
55             return 1;
56         } else {
57             /* filled one */
58             j = MDC2_BLOCK - i;
59             memcpy(&(c->data[i]), in, j);
60             len -= j;
61             in += j;
62             c->num = 0;
63             mdc2_body(c, &(c->data[0]), MDC2_BLOCK);
64         }
65     }
66     i = len & ~((size_t)MDC2_BLOCK - 1);
67     if (i > 0)
68         mdc2_body(c, in, i);
69     j = len - i;
70     if (j > 0) {
71         memcpy(&(c->data[0]), &(in[i]), j);
72         c->num = (int)j;
73     }
74     return 1;
75 }
76 
mdc2_body(MDC2_CTX * c,const unsigned char * in,size_t len)77 static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len)
78 {
79     register DES_LONG tin0, tin1;
80     register DES_LONG ttin0, ttin1;
81     DES_LONG d[2], dd[2];
82     DES_key_schedule k;
83     unsigned char *p;
84     size_t i;
85 
86     for (i = 0; i < len; i += 8) {
87         c2l(in, tin0);
88         d[0] = dd[0] = tin0;
89         c2l(in, tin1);
90         d[1] = dd[1] = tin1;
91         c->h[0] = (c->h[0] & 0x9f) | 0x40;
92         c->hh[0] = (c->hh[0] & 0x9f) | 0x20;
93 
94         DES_set_odd_parity(&c->h);
95         DES_set_key_unchecked(&c->h, &k);
96         DES_encrypt1(d, &k, 1);
97 
98         DES_set_odd_parity(&c->hh);
99         DES_set_key_unchecked(&c->hh, &k);
100         DES_encrypt1(dd, &k, 1);
101 
102         ttin0 = tin0 ^ dd[0];
103         ttin1 = tin1 ^ dd[1];
104         tin0 ^= d[0];
105         tin1 ^= d[1];
106 
107         p = c->h;
108         l2c(tin0, p);
109         l2c(ttin1, p);
110         p = c->hh;
111         l2c(ttin0, p);
112         l2c(tin1, p);
113     }
114 }
115 
MDC2_Final(unsigned char * md,MDC2_CTX * c)116 int MDC2_Final(unsigned char *md, MDC2_CTX *c)
117 {
118     unsigned int i;
119     int j;
120 
121     i = c->num;
122     j = c->pad_type;
123     if ((i > 0) || (j == 2)) {
124         if (j == 2)
125             c->data[i++] = 0x80;
126         memset(&(c->data[i]), 0, MDC2_BLOCK - i);
127         mdc2_body(c, c->data, MDC2_BLOCK);
128     }
129     memcpy(md, (char *)c->h, MDC2_BLOCK);
130     memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK);
131     return 1;
132 }
133