17f675ca7SChuck Lever /* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ 27f675ca7SChuck Lever /* 37f675ca7SChuck Lever * SunRPC GSS Kerberos 5 mechanism internal definitions 47f675ca7SChuck Lever * 57f675ca7SChuck Lever * Copyright (c) 2022 Oracle and/or its affiliates. 67f675ca7SChuck Lever */ 77f675ca7SChuck Lever 87f675ca7SChuck Lever #ifndef _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H 97f675ca7SChuck Lever #define _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H 107f675ca7SChuck Lever 11e01b2c79SChuck Lever /* 126e460c23SChuck Lever * The RFCs often specify payload lengths in bits. This helper 136e460c23SChuck Lever * converts a specified bit-length to the number of octets/bytes. 146e460c23SChuck Lever */ 156e460c23SChuck Lever #define BITS2OCTETS(x) ((x) / 8) 166e460c23SChuck Lever 176e460c23SChuck Lever struct krb5_ctx; 186e460c23SChuck Lever 196e460c23SChuck Lever struct gss_krb5_enctype { 206e460c23SChuck Lever const u32 etype; /* encryption (key) type */ 216e460c23SChuck Lever const u32 ctype; /* checksum type */ 226e460c23SChuck Lever const char *name; /* "friendly" name */ 236e460c23SChuck Lever const char *encrypt_name; /* crypto encrypt name */ 246e460c23SChuck Lever const char *aux_cipher; /* aux encrypt cipher name */ 256e460c23SChuck Lever const char *cksum_name; /* crypto checksum name */ 266e460c23SChuck Lever const u16 signalg; /* signing algorithm */ 276e460c23SChuck Lever const u16 sealalg; /* sealing algorithm */ 286e460c23SChuck Lever const u32 cksumlength; /* checksum length */ 296e460c23SChuck Lever const u32 keyed_cksum; /* is it a keyed cksum? */ 306e460c23SChuck Lever const u32 keybytes; /* raw key len, in bytes */ 316e460c23SChuck Lever const u32 keylength; /* protocol key length, in octets */ 326e460c23SChuck Lever const u32 Kc_length; /* checksum subkey length, in octets */ 336e460c23SChuck Lever const u32 Ke_length; /* encryption subkey length, in octets */ 346e460c23SChuck Lever const u32 Ki_length; /* integrity subkey length, in octets */ 356e460c23SChuck Lever 366e460c23SChuck Lever int (*import_ctx)(struct krb5_ctx *ctx, gfp_t gfp_mask); 376e460c23SChuck Lever int (*derive_key)(const struct gss_krb5_enctype *gk5e, 386e460c23SChuck Lever const struct xdr_netobj *in, 396e460c23SChuck Lever struct xdr_netobj *out, 406e460c23SChuck Lever const struct xdr_netobj *label, 416e460c23SChuck Lever gfp_t gfp_mask); 426e460c23SChuck Lever u32 (*encrypt)(struct krb5_ctx *kctx, u32 offset, 436e460c23SChuck Lever struct xdr_buf *buf, struct page **pages); 446e460c23SChuck Lever u32 (*decrypt)(struct krb5_ctx *kctx, u32 offset, u32 len, 456e460c23SChuck Lever struct xdr_buf *buf, u32 *headskip, u32 *tailskip); 466e460c23SChuck Lever u32 (*get_mic)(struct krb5_ctx *kctx, struct xdr_buf *text, 476e460c23SChuck Lever struct xdr_netobj *token); 486e460c23SChuck Lever u32 (*verify_mic)(struct krb5_ctx *kctx, struct xdr_buf *message_buffer, 496e460c23SChuck Lever struct xdr_netobj *read_token); 506e460c23SChuck Lever u32 (*wrap)(struct krb5_ctx *kctx, int offset, 516e460c23SChuck Lever struct xdr_buf *buf, struct page **pages); 526e460c23SChuck Lever u32 (*unwrap)(struct krb5_ctx *kctx, int offset, int len, 536e460c23SChuck Lever struct xdr_buf *buf, unsigned int *slack, 546e460c23SChuck Lever unsigned int *align); 556e460c23SChuck Lever }; 566e460c23SChuck Lever 576e460c23SChuck Lever /* krb5_ctx flags definitions */ 586e460c23SChuck Lever #define KRB5_CTX_FLAG_INITIATOR 0x00000001 596e460c23SChuck Lever #define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004 606e460c23SChuck Lever 616e460c23SChuck Lever struct krb5_ctx { 626e460c23SChuck Lever int initiate; /* 1 = initiating, 0 = accepting */ 636e460c23SChuck Lever u32 enctype; 646e460c23SChuck Lever u32 flags; 656e460c23SChuck Lever const struct gss_krb5_enctype *gk5e; /* enctype-specific info */ 666e460c23SChuck Lever struct crypto_sync_skcipher *enc; 676e460c23SChuck Lever struct crypto_sync_skcipher *seq; 686e460c23SChuck Lever struct crypto_sync_skcipher *acceptor_enc; 696e460c23SChuck Lever struct crypto_sync_skcipher *initiator_enc; 706e460c23SChuck Lever struct crypto_sync_skcipher *acceptor_enc_aux; 716e460c23SChuck Lever struct crypto_sync_skcipher *initiator_enc_aux; 726e460c23SChuck Lever struct crypto_ahash *acceptor_sign; 736e460c23SChuck Lever struct crypto_ahash *initiator_sign; 746e460c23SChuck Lever struct crypto_ahash *initiator_integ; 756e460c23SChuck Lever struct crypto_ahash *acceptor_integ; 766e460c23SChuck Lever u8 Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */ 776e460c23SChuck Lever u8 cksum[GSS_KRB5_MAX_KEYLEN]; 786e460c23SChuck Lever atomic_t seq_send; 796e460c23SChuck Lever atomic64_t seq_send64; 806e460c23SChuck Lever time64_t endtime; 816e460c23SChuck Lever struct xdr_netobj mech_used; 826e460c23SChuck Lever }; 836e460c23SChuck Lever 846e460c23SChuck Lever /* 85e01b2c79SChuck Lever * GSS Kerberos 5 mechanism Per-Message calls. 86e01b2c79SChuck Lever */ 87e01b2c79SChuck Lever 88e01b2c79SChuck Lever u32 gss_krb5_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text, 89e01b2c79SChuck Lever struct xdr_netobj *token); 90e01b2c79SChuck Lever u32 gss_krb5_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, 91e01b2c79SChuck Lever struct xdr_netobj *token); 92e01b2c79SChuck Lever 93e01b2c79SChuck Lever u32 gss_krb5_verify_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, 94e01b2c79SChuck Lever struct xdr_netobj *read_token); 95e01b2c79SChuck Lever u32 gss_krb5_verify_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, 96e01b2c79SChuck Lever struct xdr_netobj *read_token); 97e01b2c79SChuck Lever 98e01b2c79SChuck Lever u32 gss_krb5_wrap_v1(struct krb5_ctx *kctx, int offset, 99e01b2c79SChuck Lever struct xdr_buf *buf, struct page **pages); 100e01b2c79SChuck Lever u32 gss_krb5_wrap_v2(struct krb5_ctx *kctx, int offset, 101e01b2c79SChuck Lever struct xdr_buf *buf, struct page **pages); 102e01b2c79SChuck Lever 103e01b2c79SChuck Lever u32 gss_krb5_unwrap_v1(struct krb5_ctx *kctx, int offset, int len, 104e01b2c79SChuck Lever struct xdr_buf *buf, unsigned int *slack, 105e01b2c79SChuck Lever unsigned int *align); 106e01b2c79SChuck Lever u32 gss_krb5_unwrap_v2(struct krb5_ctx *kctx, int offset, int len, 107e01b2c79SChuck Lever struct xdr_buf *buf, unsigned int *slack, 108e01b2c79SChuck Lever unsigned int *align); 109e01b2c79SChuck Lever 110e01b2c79SChuck Lever /* 111e01b2c79SChuck Lever * Implementation internal functions 112e01b2c79SChuck Lever */ 113e01b2c79SChuck Lever 1142691a27dSChuck Lever /* Key Derivation Functions */ 1152691a27dSChuck Lever 1162691a27dSChuck Lever int krb5_derive_key_v1(const struct gss_krb5_enctype *gk5e, 1172691a27dSChuck Lever const struct xdr_netobj *inkey, 1182691a27dSChuck Lever struct xdr_netobj *outkey, 1192691a27dSChuck Lever const struct xdr_netobj *label, 1202691a27dSChuck Lever gfp_t gfp_mask); 1212691a27dSChuck Lever 1222691a27dSChuck Lever int krb5_derive_key_v2(const struct gss_krb5_enctype *gk5e, 1232691a27dSChuck Lever const struct xdr_netobj *inkey, 1242691a27dSChuck Lever struct xdr_netobj *outkey, 1252691a27dSChuck Lever const struct xdr_netobj *label, 1262691a27dSChuck Lever gfp_t gfp_mask); 1272691a27dSChuck Lever 128ae2e4d2bSChuck Lever int krb5_kdf_hmac_sha2(const struct gss_krb5_enctype *gk5e, 129ae2e4d2bSChuck Lever const struct xdr_netobj *inkey, 130ae2e4d2bSChuck Lever struct xdr_netobj *outkey, 131ae2e4d2bSChuck Lever const struct xdr_netobj *in_constant, 132ae2e4d2bSChuck Lever gfp_t gfp_mask); 133ae2e4d2bSChuck Lever 13445b4ef46SChuck Lever int krb5_kdf_feedback_cmac(const struct gss_krb5_enctype *gk5e, 13545b4ef46SChuck Lever const struct xdr_netobj *inkey, 13645b4ef46SChuck Lever struct xdr_netobj *outkey, 13745b4ef46SChuck Lever const struct xdr_netobj *in_constant, 13845b4ef46SChuck Lever gfp_t gfp_mask); 13945b4ef46SChuck Lever 1402691a27dSChuck Lever /** 1412691a27dSChuck Lever * krb5_derive_key - Derive a subkey from a protocol key 1422691a27dSChuck Lever * @kctx: Kerberos 5 context 1432691a27dSChuck Lever * @inkey: base protocol key 1442691a27dSChuck Lever * @outkey: OUT: derived key 1452691a27dSChuck Lever * @usage: key usage value 1462691a27dSChuck Lever * @seed: key usage seed (one octet) 1472691a27dSChuck Lever * @gfp_mask: memory allocation control flags 1482691a27dSChuck Lever * 1492691a27dSChuck Lever * Caller sets @outkey->len to the desired length of the derived key. 1502691a27dSChuck Lever * 1512691a27dSChuck Lever * On success, returns 0 and fills in @outkey. A negative errno value 1522691a27dSChuck Lever * is returned on failure. 1532691a27dSChuck Lever */ 1542691a27dSChuck Lever static inline int krb5_derive_key(struct krb5_ctx *kctx, 1552691a27dSChuck Lever const struct xdr_netobj *inkey, 1562691a27dSChuck Lever struct xdr_netobj *outkey, 1572691a27dSChuck Lever u32 usage, u8 seed, gfp_t gfp_mask) 1582691a27dSChuck Lever { 1592691a27dSChuck Lever const struct gss_krb5_enctype *gk5e = kctx->gk5e; 1602691a27dSChuck Lever u8 label_data[GSS_KRB5_K5CLENGTH]; 1612691a27dSChuck Lever struct xdr_netobj label = { 1622691a27dSChuck Lever .len = sizeof(label_data), 1632691a27dSChuck Lever .data = label_data, 1642691a27dSChuck Lever }; 1652691a27dSChuck Lever __be32 *p = (__be32 *)label_data; 1662691a27dSChuck Lever 1672691a27dSChuck Lever *p = cpu_to_be32(usage); 1682691a27dSChuck Lever label_data[4] = seed; 1692691a27dSChuck Lever return gk5e->derive_key(gk5e, inkey, outkey, &label, gfp_mask); 1702691a27dSChuck Lever } 1712691a27dSChuck Lever 1726e460c23SChuck Lever s32 krb5_make_seq_num(struct krb5_ctx *kctx, struct crypto_sync_skcipher *key, 1736e460c23SChuck Lever int direction, u32 seqnum, unsigned char *cksum, 1746e460c23SChuck Lever unsigned char *buf); 1756e460c23SChuck Lever 1766e460c23SChuck Lever s32 krb5_get_seq_num(struct krb5_ctx *kctx, unsigned char *cksum, 1776e460c23SChuck Lever unsigned char *buf, int *direction, u32 *seqnum); 1786e460c23SChuck Lever 1797f675ca7SChuck Lever void krb5_make_confounder(u8 *p, int conflen); 1807f675ca7SChuck Lever 1816e460c23SChuck Lever u32 make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen, 1826e460c23SChuck Lever struct xdr_buf *body, int body_offset, u8 *cksumkey, 1836e460c23SChuck Lever unsigned int usage, struct xdr_netobj *cksumout); 1846e460c23SChuck Lever 1852dbe0cacSChuck Lever u32 gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen, 1862dbe0cacSChuck Lever const struct xdr_buf *body, int body_offset, 1872dbe0cacSChuck Lever struct xdr_netobj *cksumout); 1882dbe0cacSChuck Lever 189d50b8152SChuck Lever u32 krb5_encrypt(struct crypto_sync_skcipher *key, void *iv, void *in, 190d50b8152SChuck Lever void *out, int length); 191d50b8152SChuck Lever 192d50b8152SChuck Lever u32 krb5_decrypt(struct crypto_sync_skcipher *key, void *iv, void *in, 193d50b8152SChuck Lever void *out, int length); 194d50b8152SChuck Lever 1956e460c23SChuck Lever int xdr_extend_head(struct xdr_buf *buf, unsigned int base, 1966e460c23SChuck Lever unsigned int shiftlen); 1976e460c23SChuck Lever 1986e460c23SChuck Lever int gss_encrypt_xdr_buf(struct crypto_sync_skcipher *tfm, 1996e460c23SChuck Lever struct xdr_buf *outbuf, int offset, 2006e460c23SChuck Lever struct page **pages); 2016e460c23SChuck Lever 2026e460c23SChuck Lever int gss_decrypt_xdr_buf(struct crypto_sync_skcipher *tfm, 2036e460c23SChuck Lever struct xdr_buf *inbuf, int offset); 2046e460c23SChuck Lever 205ae6ad5d0SChuck Lever u32 gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, 206ae6ad5d0SChuck Lever struct xdr_buf *buf, struct page **pages); 207ae6ad5d0SChuck Lever 208ae6ad5d0SChuck Lever u32 gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, 209ae6ad5d0SChuck Lever struct xdr_buf *buf, u32 *plainoffset, u32 *plainlen); 210ae6ad5d0SChuck Lever 2110d5b5a0fSChuck Lever u32 krb5_etm_encrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, 2120d5b5a0fSChuck Lever struct page **pages); 2130d5b5a0fSChuck Lever 2140d5b5a0fSChuck Lever u32 krb5_etm_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, 2150d5b5a0fSChuck Lever struct xdr_buf *buf, u32 *headskip, u32 *tailskip); 2160d5b5a0fSChuck Lever 217*eebd8c2dSChuck Lever #if IS_ENABLED(CONFIG_KUNIT) 218*eebd8c2dSChuck Lever void krb5_nfold(u32 inbits, const u8 *in, u32 outbits, u8 *out); 219*eebd8c2dSChuck Lever #endif 220*eebd8c2dSChuck Lever 2217f675ca7SChuck Lever #endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ 222