/* mppe.c - MPPE key implementation
*
* Copyright (c) 2020 Eivind Naess. All rights reserved.
* Copyright (c) 2008-2024 Paul Mackerras. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The name(s) of the authors of this software must not be used to
* endorse or promote products derived from this software without
* prior written permission.
*
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Set mppe_xxxx_key from the NTPasswordHashHash.
* RFC 2548 (RADIUS support) requires us to export this function (ugh).
*/
void
mppe_set_chapv1(unsigned char *rchallenge, unsigned char *PasswordHashHash)
{
PPP_MD_CTX *ctx;
u_char Digest[SHA_DIGEST_LENGTH];
unsigned int DigestLen;
ctx = PPP_MD_CTX_new();
if (ctx != NULL) {
if (PPP_DigestInit(ctx, PPP_sha1())) {
if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_DIGEST_LENGTH)) {
if (PPP_DigestUpdate(ctx, PasswordHashHash, MD4_DIGEST_LENGTH)) {
/* Same key in both directions. */
mppe_set_keys(Digest, Digest, sizeof(Digest));
}
/*
* Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079)
*
* This helper function used in the Winbind module, which gets the
* NTHashHash from the server.
*/
void
mppe_set_chapv2(unsigned char *PasswordHashHash, unsigned char *NTResponse,
int IsServer)
{
PPP_MD_CTX *ctx;
u_char MasterKey[SHA_DIGEST_LENGTH];
u_char SendKey[SHA_DIGEST_LENGTH];
u_char RecvKey[SHA_DIGEST_LENGTH];
unsigned int KeyLen;
/*
* Set MPPE options from plugins.
*/
void
mppe_set_enc_types(int policy, int types)
{
/* Early exit for unknown policies. */
if (policy != MPPE_ENC_POL_ENC_ALLOWED &&
policy != MPPE_ENC_POL_ENC_REQUIRED)
return;
/* Don't modify MPPE if it's optional and wasn't already configured. */
if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe)
return;
/*
* Disable undesirable encryption types. Note that we don't ENABLE
* any encryption types, to avoid overriding manual configuration.
*/
switch(types) {
case MPPE_ENC_TYPES_RC4_40:
ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */
break;
case MPPE_ENC_TYPES_RC4_128:
ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */
break;
default:
break;
}
}