11cb0ef41Sopenharmony_ci/*
21cb0ef41Sopenharmony_ci * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
31cb0ef41Sopenharmony_ci *
41cb0ef41Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
51cb0ef41Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
61cb0ef41Sopenharmony_ci * in the file LICENSE in the source distribution or at
71cb0ef41Sopenharmony_ci * https://www.openssl.org/source/license.html
81cb0ef41Sopenharmony_ci */
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci/*
111cb0ef41Sopenharmony_ci * RC5 low level APIs are deprecated for public use, but still ok for internal
121cb0ef41Sopenharmony_ci * use.
131cb0ef41Sopenharmony_ci */
141cb0ef41Sopenharmony_ci#include "internal/deprecated.h"
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci#include <stdio.h>
171cb0ef41Sopenharmony_ci#include "internal/cryptlib.h"
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ci#ifndef OPENSSL_NO_RC5
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci# include <openssl/evp.h>
221cb0ef41Sopenharmony_ci# include "crypto/evp.h"
231cb0ef41Sopenharmony_ci# include <openssl/objects.h>
241cb0ef41Sopenharmony_ci# include "evp_local.h"
251cb0ef41Sopenharmony_ci# include <openssl/rc5.h>
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_cistatic int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
281cb0ef41Sopenharmony_ci                               const unsigned char *iv, int enc);
291cb0ef41Sopenharmony_cistatic int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_citypedef struct {
321cb0ef41Sopenharmony_ci    int rounds;                 /* number of rounds */
331cb0ef41Sopenharmony_ci    RC5_32_KEY ks;              /* key schedule */
341cb0ef41Sopenharmony_ci} EVP_RC5_KEY;
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci# define data(ctx)       EVP_C_DATA(EVP_RC5_KEY,ctx)
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ciIMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5,
391cb0ef41Sopenharmony_ci                       8, RC5_32_KEY_LENGTH, 8, 64,
401cb0ef41Sopenharmony_ci                       EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
411cb0ef41Sopenharmony_ci                       r_32_12_16_init_key, NULL, NULL, NULL, rc5_ctrl)
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_cistatic int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
441cb0ef41Sopenharmony_ci{
451cb0ef41Sopenharmony_ci    switch (type) {
461cb0ef41Sopenharmony_ci    case EVP_CTRL_INIT:
471cb0ef41Sopenharmony_ci        data(c)->rounds = RC5_12_ROUNDS;
481cb0ef41Sopenharmony_ci        return 1;
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci    case EVP_CTRL_GET_RC5_ROUNDS:
511cb0ef41Sopenharmony_ci        *(int *)ptr = data(c)->rounds;
521cb0ef41Sopenharmony_ci        return 1;
531cb0ef41Sopenharmony_ci
541cb0ef41Sopenharmony_ci    case EVP_CTRL_SET_RC5_ROUNDS:
551cb0ef41Sopenharmony_ci        switch (arg) {
561cb0ef41Sopenharmony_ci        case RC5_8_ROUNDS:
571cb0ef41Sopenharmony_ci        case RC5_12_ROUNDS:
581cb0ef41Sopenharmony_ci        case RC5_16_ROUNDS:
591cb0ef41Sopenharmony_ci            data(c)->rounds = arg;
601cb0ef41Sopenharmony_ci            return 1;
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci        default:
631cb0ef41Sopenharmony_ci            ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS);
641cb0ef41Sopenharmony_ci            return 0;
651cb0ef41Sopenharmony_ci        }
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci    default:
681cb0ef41Sopenharmony_ci        return -1;
691cb0ef41Sopenharmony_ci    }
701cb0ef41Sopenharmony_ci}
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_cistatic int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
731cb0ef41Sopenharmony_ci                               const unsigned char *iv, int enc)
741cb0ef41Sopenharmony_ci{
751cb0ef41Sopenharmony_ci    const int key_len = EVP_CIPHER_CTX_get_key_length(ctx);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci    if (key_len > 255 || key_len < 0) {
781cb0ef41Sopenharmony_ci        ERR_raise(ERR_LIB_EVP, EVP_R_BAD_KEY_LENGTH);
791cb0ef41Sopenharmony_ci        return 0;
801cb0ef41Sopenharmony_ci    }
811cb0ef41Sopenharmony_ci    return RC5_32_set_key(&data(ctx)->ks, key_len, key, data(ctx)->rounds);
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci#endif
85