162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * SunRPC GSS Kerberos 5 mechanism internal definitions 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2022 Oracle and/or its affiliates. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H 962306a36Sopenharmony_ci#define _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* 1262306a36Sopenharmony_ci * The RFCs often specify payload lengths in bits. This helper 1362306a36Sopenharmony_ci * converts a specified bit-length to the number of octets/bytes. 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci#define BITS2OCTETS(x) ((x) / 8) 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_cistruct krb5_ctx; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistruct gss_krb5_enctype { 2062306a36Sopenharmony_ci const u32 etype; /* encryption (key) type */ 2162306a36Sopenharmony_ci const u32 ctype; /* checksum type */ 2262306a36Sopenharmony_ci const char *name; /* "friendly" name */ 2362306a36Sopenharmony_ci const char *encrypt_name; /* crypto encrypt name */ 2462306a36Sopenharmony_ci const char *aux_cipher; /* aux encrypt cipher name */ 2562306a36Sopenharmony_ci const char *cksum_name; /* crypto checksum name */ 2662306a36Sopenharmony_ci const u16 signalg; /* signing algorithm */ 2762306a36Sopenharmony_ci const u16 sealalg; /* sealing algorithm */ 2862306a36Sopenharmony_ci const u32 cksumlength; /* checksum length */ 2962306a36Sopenharmony_ci const u32 keyed_cksum; /* is it a keyed cksum? */ 3062306a36Sopenharmony_ci const u32 keybytes; /* raw key len, in bytes */ 3162306a36Sopenharmony_ci const u32 keylength; /* protocol key length, in octets */ 3262306a36Sopenharmony_ci const u32 Kc_length; /* checksum subkey length, in octets */ 3362306a36Sopenharmony_ci const u32 Ke_length; /* encryption subkey length, in octets */ 3462306a36Sopenharmony_ci const u32 Ki_length; /* integrity subkey length, in octets */ 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci int (*derive_key)(const struct gss_krb5_enctype *gk5e, 3762306a36Sopenharmony_ci const struct xdr_netobj *in, 3862306a36Sopenharmony_ci struct xdr_netobj *out, 3962306a36Sopenharmony_ci const struct xdr_netobj *label, 4062306a36Sopenharmony_ci gfp_t gfp_mask); 4162306a36Sopenharmony_ci u32 (*encrypt)(struct krb5_ctx *kctx, u32 offset, 4262306a36Sopenharmony_ci struct xdr_buf *buf, struct page **pages); 4362306a36Sopenharmony_ci u32 (*decrypt)(struct krb5_ctx *kctx, u32 offset, u32 len, 4462306a36Sopenharmony_ci struct xdr_buf *buf, u32 *headskip, u32 *tailskip); 4562306a36Sopenharmony_ci u32 (*get_mic)(struct krb5_ctx *kctx, struct xdr_buf *text, 4662306a36Sopenharmony_ci struct xdr_netobj *token); 4762306a36Sopenharmony_ci u32 (*verify_mic)(struct krb5_ctx *kctx, struct xdr_buf *message_buffer, 4862306a36Sopenharmony_ci struct xdr_netobj *read_token); 4962306a36Sopenharmony_ci u32 (*wrap)(struct krb5_ctx *kctx, int offset, 5062306a36Sopenharmony_ci struct xdr_buf *buf, struct page **pages); 5162306a36Sopenharmony_ci u32 (*unwrap)(struct krb5_ctx *kctx, int offset, int len, 5262306a36Sopenharmony_ci struct xdr_buf *buf, unsigned int *slack, 5362306a36Sopenharmony_ci unsigned int *align); 5462306a36Sopenharmony_ci}; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci/* krb5_ctx flags definitions */ 5762306a36Sopenharmony_ci#define KRB5_CTX_FLAG_INITIATOR 0x00000001 5862306a36Sopenharmony_ci#define KRB5_CTX_FLAG_ACCEPTOR_SUBKEY 0x00000004 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistruct krb5_ctx { 6162306a36Sopenharmony_ci int initiate; /* 1 = initiating, 0 = accepting */ 6262306a36Sopenharmony_ci u32 enctype; 6362306a36Sopenharmony_ci u32 flags; 6462306a36Sopenharmony_ci const struct gss_krb5_enctype *gk5e; /* enctype-specific info */ 6562306a36Sopenharmony_ci struct crypto_sync_skcipher *enc; 6662306a36Sopenharmony_ci struct crypto_sync_skcipher *seq; 6762306a36Sopenharmony_ci struct crypto_sync_skcipher *acceptor_enc; 6862306a36Sopenharmony_ci struct crypto_sync_skcipher *initiator_enc; 6962306a36Sopenharmony_ci struct crypto_sync_skcipher *acceptor_enc_aux; 7062306a36Sopenharmony_ci struct crypto_sync_skcipher *initiator_enc_aux; 7162306a36Sopenharmony_ci struct crypto_ahash *acceptor_sign; 7262306a36Sopenharmony_ci struct crypto_ahash *initiator_sign; 7362306a36Sopenharmony_ci struct crypto_ahash *initiator_integ; 7462306a36Sopenharmony_ci struct crypto_ahash *acceptor_integ; 7562306a36Sopenharmony_ci u8 Ksess[GSS_KRB5_MAX_KEYLEN]; /* session key */ 7662306a36Sopenharmony_ci u8 cksum[GSS_KRB5_MAX_KEYLEN]; 7762306a36Sopenharmony_ci atomic_t seq_send; 7862306a36Sopenharmony_ci atomic64_t seq_send64; 7962306a36Sopenharmony_ci time64_t endtime; 8062306a36Sopenharmony_ci struct xdr_netobj mech_used; 8162306a36Sopenharmony_ci}; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci/* 8462306a36Sopenharmony_ci * GSS Kerberos 5 mechanism Per-Message calls. 8562306a36Sopenharmony_ci */ 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ciu32 gss_krb5_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text, 8862306a36Sopenharmony_ci struct xdr_netobj *token); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ciu32 gss_krb5_verify_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *message_buffer, 9162306a36Sopenharmony_ci struct xdr_netobj *read_token); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ciu32 gss_krb5_wrap_v2(struct krb5_ctx *kctx, int offset, 9462306a36Sopenharmony_ci struct xdr_buf *buf, struct page **pages); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ciu32 gss_krb5_unwrap_v2(struct krb5_ctx *kctx, int offset, int len, 9762306a36Sopenharmony_ci struct xdr_buf *buf, unsigned int *slack, 9862306a36Sopenharmony_ci unsigned int *align); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci/* 10162306a36Sopenharmony_ci * Implementation internal functions 10262306a36Sopenharmony_ci */ 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci/* Key Derivation Functions */ 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ciint krb5_derive_key_v2(const struct gss_krb5_enctype *gk5e, 10762306a36Sopenharmony_ci const struct xdr_netobj *inkey, 10862306a36Sopenharmony_ci struct xdr_netobj *outkey, 10962306a36Sopenharmony_ci const struct xdr_netobj *label, 11062306a36Sopenharmony_ci gfp_t gfp_mask); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ciint krb5_kdf_hmac_sha2(const struct gss_krb5_enctype *gk5e, 11362306a36Sopenharmony_ci const struct xdr_netobj *inkey, 11462306a36Sopenharmony_ci struct xdr_netobj *outkey, 11562306a36Sopenharmony_ci const struct xdr_netobj *in_constant, 11662306a36Sopenharmony_ci gfp_t gfp_mask); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciint krb5_kdf_feedback_cmac(const struct gss_krb5_enctype *gk5e, 11962306a36Sopenharmony_ci const struct xdr_netobj *inkey, 12062306a36Sopenharmony_ci struct xdr_netobj *outkey, 12162306a36Sopenharmony_ci const struct xdr_netobj *in_constant, 12262306a36Sopenharmony_ci gfp_t gfp_mask); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci/** 12562306a36Sopenharmony_ci * krb5_derive_key - Derive a subkey from a protocol key 12662306a36Sopenharmony_ci * @kctx: Kerberos 5 context 12762306a36Sopenharmony_ci * @inkey: base protocol key 12862306a36Sopenharmony_ci * @outkey: OUT: derived key 12962306a36Sopenharmony_ci * @usage: key usage value 13062306a36Sopenharmony_ci * @seed: key usage seed (one octet) 13162306a36Sopenharmony_ci * @gfp_mask: memory allocation control flags 13262306a36Sopenharmony_ci * 13362306a36Sopenharmony_ci * Caller sets @outkey->len to the desired length of the derived key. 13462306a36Sopenharmony_ci * 13562306a36Sopenharmony_ci * On success, returns 0 and fills in @outkey. A negative errno value 13662306a36Sopenharmony_ci * is returned on failure. 13762306a36Sopenharmony_ci */ 13862306a36Sopenharmony_cistatic inline int krb5_derive_key(struct krb5_ctx *kctx, 13962306a36Sopenharmony_ci const struct xdr_netobj *inkey, 14062306a36Sopenharmony_ci struct xdr_netobj *outkey, 14162306a36Sopenharmony_ci u32 usage, u8 seed, gfp_t gfp_mask) 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci const struct gss_krb5_enctype *gk5e = kctx->gk5e; 14462306a36Sopenharmony_ci u8 label_data[GSS_KRB5_K5CLENGTH]; 14562306a36Sopenharmony_ci struct xdr_netobj label = { 14662306a36Sopenharmony_ci .len = sizeof(label_data), 14762306a36Sopenharmony_ci .data = label_data, 14862306a36Sopenharmony_ci }; 14962306a36Sopenharmony_ci __be32 *p = (__be32 *)label_data; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci *p = cpu_to_be32(usage); 15262306a36Sopenharmony_ci label_data[4] = seed; 15362306a36Sopenharmony_ci return gk5e->derive_key(gk5e, inkey, outkey, &label, gfp_mask); 15462306a36Sopenharmony_ci} 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_civoid krb5_make_confounder(u8 *p, int conflen); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ciu32 make_checksum(struct krb5_ctx *kctx, char *header, int hdrlen, 15962306a36Sopenharmony_ci struct xdr_buf *body, int body_offset, u8 *cksumkey, 16062306a36Sopenharmony_ci unsigned int usage, struct xdr_netobj *cksumout); 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ciu32 gss_krb5_checksum(struct crypto_ahash *tfm, char *header, int hdrlen, 16362306a36Sopenharmony_ci const struct xdr_buf *body, int body_offset, 16462306a36Sopenharmony_ci struct xdr_netobj *cksumout); 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ciu32 krb5_encrypt(struct crypto_sync_skcipher *key, void *iv, void *in, 16762306a36Sopenharmony_ci void *out, int length); 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ciu32 krb5_decrypt(struct crypto_sync_skcipher *key, void *iv, void *in, 17062306a36Sopenharmony_ci void *out, int length); 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ciint xdr_extend_head(struct xdr_buf *buf, unsigned int base, 17362306a36Sopenharmony_ci unsigned int shiftlen); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ciint gss_encrypt_xdr_buf(struct crypto_sync_skcipher *tfm, 17662306a36Sopenharmony_ci struct xdr_buf *outbuf, int offset, 17762306a36Sopenharmony_ci struct page **pages); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ciint gss_decrypt_xdr_buf(struct crypto_sync_skcipher *tfm, 18062306a36Sopenharmony_ci struct xdr_buf *inbuf, int offset); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ciu32 gss_krb5_aes_encrypt(struct krb5_ctx *kctx, u32 offset, 18362306a36Sopenharmony_ci struct xdr_buf *buf, struct page **pages); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ciu32 gss_krb5_aes_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, 18662306a36Sopenharmony_ci struct xdr_buf *buf, u32 *plainoffset, u32 *plainlen); 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ciu32 krb5_etm_encrypt(struct krb5_ctx *kctx, u32 offset, struct xdr_buf *buf, 18962306a36Sopenharmony_ci struct page **pages); 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ciu32 krb5_etm_decrypt(struct krb5_ctx *kctx, u32 offset, u32 len, 19262306a36Sopenharmony_ci struct xdr_buf *buf, u32 *headskip, u32 *tailskip); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_KUNIT) 19562306a36Sopenharmony_civoid krb5_nfold(u32 inbits, const u8 *in, u32 outbits, u8 *out); 19662306a36Sopenharmony_ciconst struct gss_krb5_enctype *gss_krb5_lookup_enctype(u32 etype); 19762306a36Sopenharmony_ciint krb5_cbc_cts_encrypt(struct crypto_sync_skcipher *cts_tfm, 19862306a36Sopenharmony_ci struct crypto_sync_skcipher *cbc_tfm, u32 offset, 19962306a36Sopenharmony_ci struct xdr_buf *buf, struct page **pages, 20062306a36Sopenharmony_ci u8 *iv, unsigned int ivsize); 20162306a36Sopenharmony_ciint krb5_cbc_cts_decrypt(struct crypto_sync_skcipher *cts_tfm, 20262306a36Sopenharmony_ci struct crypto_sync_skcipher *cbc_tfm, 20362306a36Sopenharmony_ci u32 offset, struct xdr_buf *buf); 20462306a36Sopenharmony_ciu32 krb5_etm_checksum(struct crypto_sync_skcipher *cipher, 20562306a36Sopenharmony_ci struct crypto_ahash *tfm, const struct xdr_buf *body, 20662306a36Sopenharmony_ci int body_offset, struct xdr_netobj *cksumout); 20762306a36Sopenharmony_ci#endif 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci#endif /* _NET_SUNRPC_AUTH_GSS_KRB5_INTERNAL_H */ 210