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 * MD2 low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <stdio.h> 17e1051a39Sopenharmony_ci#include <stdlib.h> 18e1051a39Sopenharmony_ci#include <string.h> 19e1051a39Sopenharmony_ci#include <openssl/crypto.h> 20e1051a39Sopenharmony_ci#include <openssl/des.h> 21e1051a39Sopenharmony_ci#include <openssl/mdc2.h> 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_ci#undef c2l 24e1051a39Sopenharmony_ci#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ 25e1051a39Sopenharmony_ci l|=((DES_LONG)(*((c)++)))<< 8L, \ 26e1051a39Sopenharmony_ci l|=((DES_LONG)(*((c)++)))<<16L, \ 27e1051a39Sopenharmony_ci l|=((DES_LONG)(*((c)++)))<<24L) 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_ci#undef l2c 30e1051a39Sopenharmony_ci#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ 31e1051a39Sopenharmony_ci *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ 32e1051a39Sopenharmony_ci *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ 33e1051a39Sopenharmony_ci *((c)++)=(unsigned char)(((l)>>24L)&0xff)) 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_cistatic void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); 36e1051a39Sopenharmony_ciint MDC2_Init(MDC2_CTX *c) 37e1051a39Sopenharmony_ci{ 38e1051a39Sopenharmony_ci c->num = 0; 39e1051a39Sopenharmony_ci c->pad_type = 1; 40e1051a39Sopenharmony_ci memset(&(c->h[0]), 0x52, MDC2_BLOCK); 41e1051a39Sopenharmony_ci memset(&(c->hh[0]), 0x25, MDC2_BLOCK); 42e1051a39Sopenharmony_ci return 1; 43e1051a39Sopenharmony_ci} 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ciint MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len) 46e1051a39Sopenharmony_ci{ 47e1051a39Sopenharmony_ci size_t i, j; 48e1051a39Sopenharmony_ci 49e1051a39Sopenharmony_ci i = c->num; 50e1051a39Sopenharmony_ci if (i != 0) { 51e1051a39Sopenharmony_ci if (len < MDC2_BLOCK - i) { 52e1051a39Sopenharmony_ci /* partial block */ 53e1051a39Sopenharmony_ci memcpy(&(c->data[i]), in, len); 54e1051a39Sopenharmony_ci c->num += (int)len; 55e1051a39Sopenharmony_ci return 1; 56e1051a39Sopenharmony_ci } else { 57e1051a39Sopenharmony_ci /* filled one */ 58e1051a39Sopenharmony_ci j = MDC2_BLOCK - i; 59e1051a39Sopenharmony_ci memcpy(&(c->data[i]), in, j); 60e1051a39Sopenharmony_ci len -= j; 61e1051a39Sopenharmony_ci in += j; 62e1051a39Sopenharmony_ci c->num = 0; 63e1051a39Sopenharmony_ci mdc2_body(c, &(c->data[0]), MDC2_BLOCK); 64e1051a39Sopenharmony_ci } 65e1051a39Sopenharmony_ci } 66e1051a39Sopenharmony_ci i = len & ~((size_t)MDC2_BLOCK - 1); 67e1051a39Sopenharmony_ci if (i > 0) 68e1051a39Sopenharmony_ci mdc2_body(c, in, i); 69e1051a39Sopenharmony_ci j = len - i; 70e1051a39Sopenharmony_ci if (j > 0) { 71e1051a39Sopenharmony_ci memcpy(&(c->data[0]), &(in[i]), j); 72e1051a39Sopenharmony_ci c->num = (int)j; 73e1051a39Sopenharmony_ci } 74e1051a39Sopenharmony_ci return 1; 75e1051a39Sopenharmony_ci} 76e1051a39Sopenharmony_ci 77e1051a39Sopenharmony_cistatic void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len) 78e1051a39Sopenharmony_ci{ 79e1051a39Sopenharmony_ci register DES_LONG tin0, tin1; 80e1051a39Sopenharmony_ci register DES_LONG ttin0, ttin1; 81e1051a39Sopenharmony_ci DES_LONG d[2], dd[2]; 82e1051a39Sopenharmony_ci DES_key_schedule k; 83e1051a39Sopenharmony_ci unsigned char *p; 84e1051a39Sopenharmony_ci size_t i; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci for (i = 0; i < len; i += 8) { 87e1051a39Sopenharmony_ci c2l(in, tin0); 88e1051a39Sopenharmony_ci d[0] = dd[0] = tin0; 89e1051a39Sopenharmony_ci c2l(in, tin1); 90e1051a39Sopenharmony_ci d[1] = dd[1] = tin1; 91e1051a39Sopenharmony_ci c->h[0] = (c->h[0] & 0x9f) | 0x40; 92e1051a39Sopenharmony_ci c->hh[0] = (c->hh[0] & 0x9f) | 0x20; 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_ci DES_set_odd_parity(&c->h); 95e1051a39Sopenharmony_ci DES_set_key_unchecked(&c->h, &k); 96e1051a39Sopenharmony_ci DES_encrypt1(d, &k, 1); 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci DES_set_odd_parity(&c->hh); 99e1051a39Sopenharmony_ci DES_set_key_unchecked(&c->hh, &k); 100e1051a39Sopenharmony_ci DES_encrypt1(dd, &k, 1); 101e1051a39Sopenharmony_ci 102e1051a39Sopenharmony_ci ttin0 = tin0 ^ dd[0]; 103e1051a39Sopenharmony_ci ttin1 = tin1 ^ dd[1]; 104e1051a39Sopenharmony_ci tin0 ^= d[0]; 105e1051a39Sopenharmony_ci tin1 ^= d[1]; 106e1051a39Sopenharmony_ci 107e1051a39Sopenharmony_ci p = c->h; 108e1051a39Sopenharmony_ci l2c(tin0, p); 109e1051a39Sopenharmony_ci l2c(ttin1, p); 110e1051a39Sopenharmony_ci p = c->hh; 111e1051a39Sopenharmony_ci l2c(ttin0, p); 112e1051a39Sopenharmony_ci l2c(tin1, p); 113e1051a39Sopenharmony_ci } 114e1051a39Sopenharmony_ci} 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ciint MDC2_Final(unsigned char *md, MDC2_CTX *c) 117e1051a39Sopenharmony_ci{ 118e1051a39Sopenharmony_ci unsigned int i; 119e1051a39Sopenharmony_ci int j; 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci i = c->num; 122e1051a39Sopenharmony_ci j = c->pad_type; 123e1051a39Sopenharmony_ci if ((i > 0) || (j == 2)) { 124e1051a39Sopenharmony_ci if (j == 2) 125e1051a39Sopenharmony_ci c->data[i++] = 0x80; 126e1051a39Sopenharmony_ci memset(&(c->data[i]), 0, MDC2_BLOCK - i); 127e1051a39Sopenharmony_ci mdc2_body(c, c->data, MDC2_BLOCK); 128e1051a39Sopenharmony_ci } 129e1051a39Sopenharmony_ci memcpy(md, (char *)c->h, MDC2_BLOCK); 130e1051a39Sopenharmony_ci memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK); 131e1051a39Sopenharmony_ci return 1; 132e1051a39Sopenharmony_ci} 133