Received: by 2002:ab2:6203:0:b0:1f5:f2ab:c469 with SMTP id o3csp986404lqt; Fri, 19 Apr 2024 17:56:24 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWH10VsQFg0vHAuX0/0ax2noAtKfSTa2fTfx3Td66Kk3YIXftUt2TGViM3xcT6wnSSUWUWkXl33xqa9C3JavHPU7glK+z1Gbbaw4sxYjg== X-Google-Smtp-Source: AGHT+IHkNlc6XjmWcOK+HpVPH4vO/2owV1AoG9c2zR1PGcU6YZgymCrHRFE213mmOAE5uwWs7lZQ X-Received: by 2002:a17:902:c942:b0:1e4:b1eb:7dee with SMTP id i2-20020a170902c94200b001e4b1eb7deemr4470654pla.47.1713574584396; Fri, 19 Apr 2024 17:56:24 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1713574584; cv=pass; d=google.com; s=arc-20160816; b=BtfSZ4ak0BoenNieucDxGiDS+Bq4H4ix4Tpi9DIfjdlNwIRE8q0LlWW3CQZAMp19AU Hv2o9CL1GH2q/Ovp+sbBOac/G9z5jbxj4amJbikgkAeY035t6Ot9YCVR5uemFVEmz1gp yoKgy2+SCzhlsX3PQT/sgvNQzuiwcQLn6lga5EfdORiRVF5bHr2fv1KjMqd5O1sBz3oj 9Z8xm1NP4lwAtQrN6hxl47ILcyqCxNqEmP88xbfDzC4smucww5hbGIHn1/OQvMql4MrN h1ZvUe2Wr2RbvNL6j10u2EdXnhukW+SuOTsGmPS2zB939fvDDqmDXYjIRh+22nm3f6AN lGOQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:dkim-signature:message-id; bh=TWxFuS8KOGm1Mkg9vTQ1ba95s1SAyh91PE+9f7p1nK4=; fh=zF0mnFNF65OG9v9U1qYqsxVSdPS1T0QLA3n7bTzI3/E=; b=IdsSbRdis2wO5IvRG5LVe8RYqrRJQV3QfDSOUDFbU9CizruvGIwUfqtAYpM/wALgrZ x9y3f/8pPS8sHhE8ZMk0fIeW12ihIf1BVl2Rr46epb1crg7Ngff4La4pQxUs1cFOxx3D yKjg/Y/Zza3Gi6IraW1Jfjpb4PMt9F4ptdtt7SEWE1EfTqVJ2mJk5pYFbmlH9ufXWkXw 2h4DYmJh1rsmhXtmX/01lXHQqm7kvHaq2EIrbyVAp/Fuwod5HGiFx9Zn7Kmfqt15wie5 ICEdoLbU+G8JLqBYeEpHEhBStVNX8gYEr4ij3jY2QZM65FlAwVVjIZEj55bV6yRMLsHQ T4xA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=kMtNY03x; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-crypto+bounces-3725-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-crypto+bounces-3725-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id q2-20020a170902dac200b001e4b20bb0b0si4086212plx.326.2024.04.19.17.56.24 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 19 Apr 2024 17:56:24 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-crypto+bounces-3725-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=kMtNY03x; arc=pass (i=1 spf=pass spfdomain=linux.dev dkim=pass dkdomain=linux.dev dmarc=pass fromdomain=linux.dev); spf=pass (google.com: domain of linux-crypto+bounces-3725-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-crypto+bounces-3725-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id F20592816A2 for ; Sat, 20 Apr 2024 00:56:23 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3A9746FB0; Sat, 20 Apr 2024 00:56:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="kMtNY03x" X-Original-To: linux-crypto@vger.kernel.org Received: from out-172.mta0.migadu.com (out-172.mta0.migadu.com [91.218.175.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 41CBE63E for ; Sat, 20 Apr 2024 00:56:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713574575; cv=none; b=H6iAn0jrhYZ/zTEQsmT/xYQFMAd5Px86U72R94oi7nRX553QAVXnqXsXlyBwBaDRd2vDQImT4lKX0nfyt9dJPSjslPM2MuqryeFIf72Mc6OM4LeSQMjPfkmVpmv3QEcAB6wF+KgNsPuGVned+BejX9y5XztNLeC4yHnaaEJpMXU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713574575; c=relaxed/simple; bh=hBy6UTxY8N6D6OUw4axcPvqvdd9zcGecFDPuS3bAFvg=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=ot8OMRmXhJT2FqOx46vxCypRpCFn4f6kJjXWyMnJugbGQuIUo/5DAlefq2XoBgLreaCkncqKVH1aE5tY3kzoGJUI9YNUBVBKJ5bnWBkOapSaBIsPsnp5Kuz2O/6ewaoW9KLzoTfIFCZox9rggcta2AK3vFM8aAQVRqkrkZGq3wY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=kMtNY03x; arc=none smtp.client-ip=91.218.175.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Message-ID: <05869e15-fb3b-494f-bf80-43d5f0be89fa@linux.dev> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1713574568; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TWxFuS8KOGm1Mkg9vTQ1ba95s1SAyh91PE+9f7p1nK4=; b=kMtNY03xnAc1GKnOG82peaexe/8RtbdsmHf8Y0xObxrAE2IPkcRjhReayXG1ObZOv4xsQp j5IrL9oV+whPXmEvaOB4T/svRdrS6ATTqDNE5WxzlNFvDz0wCvFft4x+5YSRxFMniD2eex Lo4ViX8c90sVbKuvv6O+qHN6+dlB+wk= Date: Sat, 20 Apr 2024 01:56:06 +0100 Precedence: bulk X-Mailing-List: linux-crypto@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: Re: [PATCH bpf-next v9 3/4] selftests: bpf: crypto skcipher algo selftests To: Martin KaFai Lau , Vadim Fedorenko Cc: Jakub Kicinski , Andrii Nakryiko , Alexei Starovoitov , Mykola Lysenko , Herbert Xu , netdev@vger.kernel.org, linux-crypto@vger.kernel.org, bpf@vger.kernel.org References: <20240416204004.3942393-1-vadfed@meta.com> <20240416204004.3942393-4-vadfed@meta.com> <60a88a78-d6d5-48b9-b894-47e4e54240df@linux.dev> Content-Language: en-US X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Vadim Fedorenko In-Reply-To: <60a88a78-d6d5-48b9-b894-47e4e54240df@linux.dev> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT On 19/04/2024 22:38, Martin KaFai Lau wrote: > On 4/16/24 1:40 PM, Vadim Fedorenko wrote: >> +void test_crypto_sanity(void) >> +{ >> +    struct crypto_syscall_args sargs = { >> +        .key_len = 16, >> +    }; >> +    LIBBPF_OPTS(bpf_tc_hook, qdisc_hook, .attach_point = BPF_TC_EGRESS); >> +    LIBBPF_OPTS(bpf_tc_opts, tc_attach_enc); >> +    LIBBPF_OPTS(bpf_tc_opts, tc_attach_dec); >> +    LIBBPF_OPTS(bpf_test_run_opts, opts, >> +            .ctx_in = &sargs, >> +            .ctx_size_in = sizeof(sargs), >> +    ); >> +    struct nstoken *nstoken = NULL; >> +    struct crypto_sanity *skel; >> +    char afalg_plain[16] = {0}; >> +    char afalg_dst[16] = {0}; >> +    struct sockaddr_in6 addr; >> +    int sockfd, err, pfd; >> +    socklen_t addrlen; >> + >> +    SYS(fail, "ip netns add %s", NS_TEST); >> +    SYS(fail, "ip -net %s -6 addr add %s/128 dev lo nodad", NS_TEST, >> IPV6_IFACE_ADDR); >> +    SYS(fail, "ip -net %s link set dev lo up", NS_TEST); >> + >> +    nstoken = open_netns(NS_TEST); >> +    if (!ASSERT_OK_PTR(nstoken, "open_netns")) >> +        goto fail; > > skel is not initialized. The "fail:" case needs it. > >> + >> +    err = init_afalg(); >> +    if (!ASSERT_OK(err, "AF_ALG init fail")) >> +        goto fail; >> + >> +    qdisc_hook.ifindex = if_nametoindex("lo"); >> +    if (!ASSERT_GT(qdisc_hook.ifindex, 0, "if_nametoindex lo")) >> +        goto fail; >> + >> +    skel = crypto_sanity__open_and_load(); >> +    if (!ASSERT_OK_PTR(skel, "skel open")) >> +        return; > > The netns "crypto_sanity_ns" is not deleted. > I'll re-arrange skel init and open_netns. Dunno why it was moved, it should be other way. >> + >> +    memcpy(skel->bss->key, crypto_key, sizeof(crypto_key)); >> +    snprintf(skel->bss->algo, 128, "%s", algo); >> +    pfd = bpf_program__fd(skel->progs.skb_crypto_setup); >> +    if (!ASSERT_GT(pfd, 0, "skb_crypto_setup fd")) >> +        goto fail; >> + >> +    err = bpf_prog_test_run_opts(pfd, &opts); >> +    if (!ASSERT_OK(err, "skb_crypto_setup") || >> +        !ASSERT_OK(opts.retval, "skb_crypto_setup retval")) >> +        goto fail; >> + >> +    if (!ASSERT_OK(skel->bss->status, "skb_crypto_setup status")) >> +        goto fail; >> + >> +    err = crypto_sanity__attach(skel); > > This attach is a left over from previous revision? > Looks like it is. >> +    if (!ASSERT_OK(err, "crypto_sanity__attach")) >> +        goto fail; >> + >> +    err = bpf_tc_hook_create(&qdisc_hook); >> +    if (!ASSERT_OK(err, "create qdisc hook")) >> +        goto fail; >> + >> +    addrlen = sizeof(addr); >> +    err = make_sockaddr(AF_INET6, IPV6_IFACE_ADDR, UDP_TEST_PORT, >> +                (void *)&addr, &addrlen); >> +    if (!ASSERT_OK(err, "make_sockaddr")) >> +        goto fail; >> + >> +    tc_attach_enc.prog_fd = bpf_program__fd(skel->progs.encrypt_sanity); >> +    err = bpf_tc_attach(&qdisc_hook, &tc_attach_enc); >> +    if (!ASSERT_OK(err, "attach encrypt filter")) >> +        goto fail; >> + >> +    sockfd = socket(AF_INET6, SOCK_DGRAM, 0); >> +    if (!ASSERT_NEQ(sockfd, -1, "encrypt socket")) >> +        goto fail; >> +    err = sendto(sockfd, plain_text, sizeof(plain_text), 0, (void >> *)&addr, addrlen); >> +    close(sockfd); >> +    if (!ASSERT_EQ(err, sizeof(plain_text), "encrypt send")) >> +        goto fail; >> + >> +    do_crypt_afalg(plain_text, afalg_dst, sizeof(afalg_dst), true); >> + >> +    bpf_tc_detach(&qdisc_hook, &tc_attach_enc); > > Check error. > > I suspect this detach should have failed because at least the > tc_attach_enc.prog_fd is not 0. > > The following attach (&tc_attach_"dec") may just happen to have a higher > priority such that the left over here does not matter. It is still > better to get it right. > Ok, I'll follow the way of tc_opts test >> +    if (!ASSERT_OK(skel->bss->status, "encrypt status")) >> +        goto fail; >> +    if (!ASSERT_STRNEQ(skel->bss->dst, afalg_dst, sizeof(afalg_dst), >> "encrypt AF_ALG")) >> +        goto fail; >> + >> +    tc_attach_dec.prog_fd = bpf_program__fd(skel->progs.decrypt_sanity); >> +    err = bpf_tc_attach(&qdisc_hook, &tc_attach_dec); >> +    if (!ASSERT_OK(err, "attach decrypt filter")) >> +        goto fail; >> + >> +    sockfd = socket(AF_INET6, SOCK_DGRAM, 0); >> +    if (!ASSERT_NEQ(sockfd, -1, "decrypt socket")) >> +        goto fail; >> +    err = sendto(sockfd, afalg_dst, sizeof(afalg_dst), 0, (void >> *)&addr, addrlen); >> +    close(sockfd); >> +    if (!ASSERT_EQ(err, sizeof(afalg_dst), "decrypt send")) >> +        goto fail; >> + >> +    do_crypt_afalg(afalg_dst, afalg_plain, sizeof(afalg_plain), false); >> + >> +    bpf_tc_detach(&qdisc_hook, &tc_attach_dec); >> +    if (!ASSERT_OK(skel->bss->status, "decrypt status")) >> +        goto fail; >> +    if (!ASSERT_STRNEQ(skel->bss->dst, afalg_plain, >> sizeof(afalg_plain), "decrypt AF_ALG")) >> +        goto fail; >> + >> +fail: >> +    if (nstoken) { > > No need to check NULL. close_netns() can handle it. > >> +        bpf_tc_hook_destroy(&qdisc_hook); > > This also does not destroy the clsact qdisc. Although the function name > feels like it would, from a quick look at bpf_tc_hook_destroy, it > depends on both BPF_TC_INGRESS and BPF_TC_EGRESS are set in the > qdisc_hook.attach_point. > > I would skip the whole bpf_tc_hook_destroy. It will go away together > with the netns. > Got it > [ ... ] > >> diff --git a/tools/testing/selftests/bpf/progs/crypto_sanity.c >> b/tools/testing/selftests/bpf/progs/crypto_sanity.c >> new file mode 100644 >> index 000000000000..57df5776bcaf >> --- /dev/null >> +++ b/tools/testing/selftests/bpf/progs/crypto_sanity.c >> @@ -0,0 +1,161 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ >> + >> +#include "vmlinux.h" >> +#include "bpf_tracing_net.h" >> +#include >> +#include >> +#include >> +#include "bpf_misc.h" >> +#include "bpf_kfuncs.h" >> +#include "crypto_common.h" >> + >> +unsigned char key[256] = {}; >> +char algo[128] = {}; >> +char dst[16] = {}; >> +int status; >> + >> +static int skb_dynptr_validate(struct __sk_buff *skb, struct >> bpf_dynptr *psrc) >> +{ >> +    struct ipv6hdr ip6h; >> +    struct udphdr udph; >> +    u32 offset; >> + >> +    if (skb->protocol != __bpf_constant_htons(ETH_P_IPV6)) >> +        return -1; >> + >> +    if (bpf_skb_load_bytes(skb, ETH_HLEN, &ip6h, sizeof(ip6h))) >> +        return -1; >> + >> +    if (ip6h.nexthdr != IPPROTO_UDP) >> +        return -1; >> + >> +    if (bpf_skb_load_bytes(skb, ETH_HLEN + sizeof(ip6h), &udph, >> sizeof(udph))) >> +        return -1; >> + >> +    if (udph.dest != __bpf_constant_htons(UDP_TEST_PORT)) >> +        return -1; >> + >> +    offset = ETH_HLEN + sizeof(ip6h) + sizeof(udph); >> +    if (skb->len < offset + 16) >> +        return -1; >> + >> +    /* let's make sure that 16 bytes of payload are in the linear >> part of skb */ >> +    bpf_skb_pull_data(skb, offset + 16); >> +    bpf_dynptr_from_skb(skb, 0, psrc); >> +    bpf_dynptr_adjust(psrc, offset, offset + 16); >> + >> +    return 0; >> +} >> + >> +SEC("syscall") >> +int skb_crypto_setup(struct crypto_syscall_args *ctx) >> +{ >> +    struct bpf_crypto_params params = { >> +        .type = "skcipher", >> +        .key_len = ctx->key_len, >> +        .authsize = ctx->authsize, >> +    }; >> +    struct bpf_crypto_ctx *cctx; >> +    int err = 0; >> + >> +    status = 0; >> + >> +    if (ctx->key_len > 255) { > > key_len == 256 won't work ? Yeah, you are right, I'll adjust the check > >> +        status = -EINVAL; >> +        return 0; >> +    } >> + >> +    __builtin_memcpy(¶ms.algo, algo, sizeof(algo)); >> +    __builtin_memcpy(¶ms.key, key, sizeof(key)); > > It will be useful to comment here what problem was hit such that the key > cannot be passed in the "struct crypto_syscall_args" and need to go back > to the global variable. Ok, I'll add some details. > Instead of "key_len" in the crypto_syscall_args and the actual "key" in > global, how about skip using the "struct crypto_syscall_args" altogether > and put key_len (and authsize) in the global? > > Put UDP_TEST_PORT as a global variable for config/filter usage also and > the "crypto_share.h" can go away. > Yeah, I can do it. >> +    cctx = bpf_crypto_ctx_create(¶ms, &err); >> + >> +    if (!cctx) { >> +        status = err; >> +        return 0; >> +    } >> + >> +    err = crypto_ctx_insert(cctx); >> +    if (err && err != -EEXIST) >> +        status = err; >> + >> +    return 0; >> +} >> + >> +SEC("tc") >> +int decrypt_sanity(struct __sk_buff *skb) >> +{ >> +    struct __crypto_ctx_value *v; >> +    struct bpf_crypto_ctx *ctx; >> +    struct bpf_dynptr psrc, pdst, iv; >> +    int err; >> + >> +    err = skb_dynptr_validate(skb, &psrc); >> +    if (err < 0) { >> +        status = err; >> +        return TC_ACT_SHOT; >> +    } >> + >> +    v = crypto_ctx_value_lookup(); >> +    if (!v) { >> +        status = -ENOENT; >> +        return TC_ACT_SHOT; >> +    } >> + >> +    ctx = v->ctx; >> +    if (!ctx) { >> +        status = -ENOENT; >> +        return TC_ACT_SHOT; >> +    } >> + >> +    bpf_dynptr_from_mem(dst, sizeof(dst), 0, &pdst); > > dst is now a global which makes it easier to test the result. A comment > here to note this point for people referencing this test for production > use case and suggest a percpu map could be used. Ok > It will be useful to have dynptr working with stack memory in the future. Another follow-up? >> +    /* iv dynptr has to be initialized with 0 size, but proper memory >> region >> +     * has to be provided anyway >> +     */ >> +    bpf_dynptr_from_mem(dst, 0, 0, &iv); >> + >> +    status = bpf_crypto_decrypt(ctx, &psrc, &pdst, &iv); >> + >> +    return TC_ACT_SHOT; >> +} >> + >> +SEC("tc") >> +int encrypt_sanity(struct __sk_buff *skb) >> +{ >> +    struct __crypto_ctx_value *v; >> +    struct bpf_crypto_ctx *ctx; >> +    struct bpf_dynptr psrc, pdst, iv; >> +    int err; >> + >> +    status = 0; >> + >> +    err = skb_dynptr_validate(skb, &psrc); >> +    if (err < 0) { >> +        status = err; >> +        return TC_ACT_SHOT; >> +    } >> + >> +    v = crypto_ctx_value_lookup(); >> +    if (!v) { >> +        status = -ENOENT; >> +        return TC_ACT_SHOT; >> +    } >> + >> +    ctx = v->ctx; >> +    if (!ctx) { >> +        status = -ENOENT; >> +        return TC_ACT_SHOT; >> +    } >> + >> +    bpf_dynptr_from_mem(dst, sizeof(dst), 0, &pdst); >> +    /* iv dynptr has to be initialized with 0 size, but proper memory >> region >> +     * has to be provided anyway >> +     */ >> +    bpf_dynptr_from_mem(dst, 0, 0, &iv); >> + >> +    status = bpf_crypto_encrypt(ctx, &psrc, &pdst, &iv); >> + >> +    return TC_ACT_SHOT; >> +} >> + >> +char __license[] SEC("license") = "GPL"; >> diff --git a/tools/testing/selftests/bpf/progs/crypto_share.h >> b/tools/testing/selftests/bpf/progs/crypto_share.h >> new file mode 100644 >> index 000000000000..c5a6ef65156d >> --- /dev/null >> +++ b/tools/testing/selftests/bpf/progs/crypto_share.h >> @@ -0,0 +1,10 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ >> + >> +#define UDP_TEST_PORT 7777 >> + >> +struct crypto_syscall_args { >> +    u32 key_len; >> +    u32 authsize; >> +}; >> + >